Codi Testing Patterns
Codi Testing Patterns
When to Use This Skill
Use this skill when implementing codi testing patterns patterns in your codebase.
How to Use This Skill
- Review the patterns and examples below
- Apply the relevant patterns to your implementation
- Follow the best practices outlined in this skill
Level 1: Quick Reference (Under 500 tokens)
Test Organization
// Feature-based test structure
describe('UserAuthentication', () => {
describe('login', () => {
it('should authenticate valid credentials', async () => {
const result = await login('user@test.com', 'password');
expect(result.success).toBe(true);
});
it('should reject invalid credentials', async () => {
await expect(login('user@test.com', 'wrong'))
.rejects.toThrow('Invalid credentials');
});
});
});
Coverage Thresholds
// vitest.config.ts
export default {
coverage: {
provider: 'v8',
thresholds: {
lines: 80,
branches: 75,
functions: 80,
statements: 80,
},
},
};
Level 2: Implementation Details (Under 2000 tokens)
Test Factory Pattern
interface UserFactory {
create(overrides?: Partial<User>): User;
createMany(count: number): User[];
}
const userFactory: UserFactory = {
create(overrides = {}) {
return {
id: crypto.randomUUID(),
email: `user-${Date.now()}@test.com`,
name: 'Test User',
createdAt: new Date(),
...overrides,
};
},
createMany(count) {
return Array.from({ length: count }, () => this.create());
},
};
// Usage
const user = userFactory.create({ name: 'Custom Name' });
const users = userFactory.createMany(10);
Mock Patterns
// Service mock with spies
const mockUserService = {
getUser: vi.fn(),
updateUser: vi.fn(),
deleteUser: vi.fn(),
};
beforeEach(() => {
mockUserService.getUser.mockResolvedValue(userFactory.create());
mockUserService.updateUser.mockResolvedValue({ success: true });
});
afterEach(() => {
vi.clearAllMocks();
});
Integration Test Helpers
async function setupTestDatabase() {
const db = await createTestDatabase();
await runMigrations(db);
return {
db,
cleanup: () => db.destroy(),
};
}
describe('UserRepository', () => {
let db: Database;
let cleanup: () => Promise<void>;
beforeAll(async () => {
({ db, cleanup } = await setupTestDatabase());
});
afterAll(() => cleanup());
it('should create user', async () => {
const repo = new UserRepository(db);
const user = await repo.create(userFactory.create());
expect(user.id).toBeDefined();
});
});
Level 3: Complete Reference (Full tokens)
E2E Test Infrastructure
// Playwright page object
class LoginPage {
constructor(private page: Page) {}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.page.fill('[data-testid="email"]', email);
await this.page.fill('[data-testid="password"]', password);
await this.page.click('[data-testid="submit"]');
}
async expectError(message: string) {
await expect(this.page.locator('.error')).toHaveText(message);
}
async expectRedirectTo(path: string) {
await this.page.waitForURL(`**${path}`);
}
}
test('user can login', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('user@test.com', 'password');
await loginPage.expectRedirectTo('/dashboard');
});
Best Practices:
- Use factories for test data
- Isolate tests with proper setup/teardown
- Implement page objects for E2E
- Set meaningful coverage thresholds
- Run tests in CI on every commit
Success Output
When successful, this skill MUST output:
✅ SKILL COMPLETE: codi-testing-patterns
Completed:
- [x] Test organization patterns applied
- [x] Coverage thresholds configured
- [x] Test factories implemented
- [x] Integration test helpers created
- [x] E2E page objects established
Outputs:
- Test files with proper describe/it structure
- vitest.config.ts with coverage thresholds
- Test factories for domain models
- Integration test setup/teardown helpers
- E2E page object classes
Completion Checklist
Before marking this skill as complete, verify:
- Tests organized by feature with clear describe blocks
- Coverage thresholds set (80% lines, 75% branches)
- Test factory pattern implemented for test data
- Mock patterns established with proper cleanup
- Integration tests have database setup/teardown
- E2E tests use page object pattern
- All tests pass in CI environment
- Test outputs are deterministic and isolated
Failure Indicators
This skill has FAILED if:
- ❌ Tests are not isolated (shared state between tests)
- ❌ Coverage thresholds not configured or below 70%
- ❌ Tests use hardcoded data instead of factories
- ❌ Mock cleanup missing (tests pollute each other)
- ❌ E2E tests use brittle selectors (no data-testid)
- ❌ Integration tests don't clean up database
- ❌ Tests fail intermittently in CI
- ❌ Test files lack clear organization structure
When NOT to Use
Do NOT use this skill when:
- Only need to run existing tests (use
testing-specialistagent instead) - Writing simple unit tests for pure functions (use basic test patterns)
- Need test execution/reporting only (use
/testcommand) - Implementing specific framework tests (use framework-specific skills like
vitest-patternsorplaywright-patterns) - Need security/penetration testing (use
security-testing-patternsskill) - Performance/load testing required (use
performance-testing-patternsskill)
Use alternative skills:
vitest-patterns- Vitest-specific configuration and featuresplaywright-patterns- Playwright-specific E2E patternstesting-specialist- General test execution and debuggingtdd-workflow- Test-driven development workflow
Anti-Patterns (Avoid)
| Anti-Pattern | Problem | Solution |
|---|---|---|
| Shared test state | Tests fail when run in different order | Use beforeEach/afterEach for isolation |
| No test factories | Brittle tests with hardcoded data | Implement factory pattern for test data |
| Missing mock cleanup | Mocks leak between tests | Use afterEach(() => vi.clearAllMocks()) |
| Direct DOM selection | E2E tests break on UI changes | Use data-testid attributes with page objects |
| No database cleanup | Integration tests pollute database | Implement proper teardown in afterAll |
| Testing implementation | Tests break on refactoring | Test behavior, not implementation details |
| Low coverage thresholds | Poor test quality acceptance | Set minimum 80% coverage thresholds |
| Skipped tests in CI | False confidence in test suite | Never skip tests; fix or remove them |
Principles
This skill embodies these CODITECT principles:
- #1 Separation of Concerns - Test organization mirrors feature structure
- #3 Keep It Simple - Use factories and helpers to simplify test code
- #5 Eliminate Ambiguity - Clear test names and assertion messages
- #6 Clear, Understandable, Explainable - Tests serve as living documentation
- #8 No Assumptions - Explicit setup/teardown, no shared state
- #9 Search Before Create - Reuse test factories and helpers across test suites
Full Principles: CODITECT-STANDARD-AUTOMATION.md