Backend - Development

Testing Guide

Testing Configuration

The project uses Jest as the main testing framework, configured in package.json:

{
  "moduleFileExtensions": ["js", "json", "ts"],
  "rootDir": "src",
  "testRegex": ".*\\.spec\\.ts$",
  "transform": {
    "^.+\\.(t|j)s$": "ts-jest"
  },
  "collectCoverageFrom": ["**/*.(t|j)s"],
  "coverageDirectory": "../coverage",
  "testEnvironment": "node"
}

Backend Tests

Service Tests

Example from ComposeService tests (compose.service.spec.ts):

describe('ComposeService', () => {
    const projectId = 'test_project';
    const path = `${__dirname.split('/api')[0]}/workspaces`;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            providers: [ComposeService],
        }).compile();
    });

    describe('readComposeFile', () => {
        // Test implementation
    });

    describe('parseServices', () => {
        // Test implementation
    });
});

E2E Tests

Located in /test directory, using supertest for API testing. Configure using jest-e2e.json:

{
  "moduleFileExtensions": ["js", "json", "ts"],
  "rootDir": ".",
  "testEnvironment": "node",
  "testRegex": ".e2e-spec.ts$",
  "transform": {
    "^.+\\.(t|j)s$": "ts-jest"
  }
}

Test Types

Unit Tests

  • Service tests (e.g., auth.service.spec.ts)
  • Controller tests
  • Repository tests

Integration Tests

  • Database integration tests using Prisma
  • External service integration (GitHub, etc.)
  • WebSocket communication tests

E2E Tests

  • API endpoint testing
  • Authentication flow testing
  • Project lifecycle testing

Mock Examples

Service Mocks

From domains.mock.ts:

export const domainsMock = {
    // Mock implementation
};

Testing Utilities

Authentication Testing

describe('AuthService', () => {
    it('should validate user credentials', async () => {
        // Test implementation
    });
});

Database Testing

Using Prisma's test utilities:

beforeEach(async () => {
    await prisma.cleanDatabase();
});

Testing Best Practices

  1. Test Organization

    • Group tests by feature/module
    • Use descriptive test names
    • Follow the Arrange-Act-Assert pattern
  2. Database Testing

    • Use separate test database
    • Clean up after each test
    • Use transactions for isolation
  3. Mock External Services

    • GitHub API calls
    • Email services
    • Third-party integrations
  4. CI Integration

    # Commands used in CI pipeline
    yarn test        # Run unit tests
    yarn test:e2e    # Run E2E tests
    yarn test:cov    # Generate coverage report
    

Writing Tests

Service Test Template

describe('YourService', () => {
    let service: YourService;
    let dependencies: MockDependencies;

    beforeEach(async () => {
        dependencies = createMockDependencies();
        service = new YourService(dependencies);
    });

    it('should do something specific', async () => {
        // Arrange
        const input = {};
        
        // Act
        const result = await service.doSomething(input);
        
        // Assert
        expect(result).toBeDefined();
    });
});

Controller Test Template

describe('YourController', () => {
    let controller: YourController;
    let service: YourService;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            controllers: [YourController],
            providers: [
                {
                    provide: YourService,
                    useValue: mockYourService,
                },
            ],
        }).compile();

        controller = module.get<YourController>(YourController);
        service = module.get<YourService>(YourService);
    });

    it('should handle requests correctly', async () => {
        // Test implementation
    });
});
Previous
API