testing-strategy
Comprehensive testing strategies including test pyramid, TDD methodology, testing patterns, coverage goals, and CI/CD integration. Use when writing tests, implementing TDD, reviewing test coverage, debugging test failures, or setting up testing infrastructure.
What this skill does
# Testing Strategy
This skill provides comprehensive guidance for implementing effective testing strategies across your entire application stack.
## Test Pyramid
### The Testing Hierarchy
```
/\
/ \
/E2E \ 10% - End-to-End Tests (slowest, most expensive)
/______\
/ \
/Integration\ 20% - Integration Tests (medium speed/cost)
/____________\
/ \
/ Unit Tests \ 70% - Unit Tests (fast, cheap, focused)
/__________________\
```
**Rationale**:
- **70% Unit Tests**: Fast, isolated, catch bugs early
- **20% Integration Tests**: Test component interactions
- **10% E2E Tests**: Test critical user journeys
### Why This Distribution?
**Unit tests are cheap**:
- Run in milliseconds
- No external dependencies
- Easy to debug
- High code coverage per test
**Integration tests are moderate**:
- Test real interactions
- Catch integration bugs
- Slower than unit tests
- More complex setup
**E2E tests are expensive**:
- Test entire system
- Catch UX issues
- Very slow (seconds/minutes)
- Brittle and hard to maintain
## TDD (Test-Driven Development)
### Red-Green-Refactor Cycle
**1. Red - Write a failing test**:
```typescript
describe('Calculator', () => {
test('adds two numbers', () => {
const calculator = new Calculator();
expect(calculator.add(2, 3)).toBe(5); // FAILS - method doesn't exist
});
});
```
**2. Green - Write minimal code to pass**:
```typescript
class Calculator {
add(a: number, b: number): number {
return a + b; // Simplest implementation
}
}
// Test now PASSES
```
**3. Refactor - Improve the code**:
```typescript
class Calculator {
add(a: number, b: number): number {
// Add validation
if (!Number.isFinite(a) || !Number.isFinite(b)) {
throw new Error('Arguments must be finite numbers');
}
return a + b;
}
}
```
### TDD Benefits
**Design benefits**:
- Forces you to think about API before implementation
- Leads to more testable, modular code
- Encourages SOLID principles
**Quality benefits**:
- 100% test coverage by design
- Catches bugs immediately
- Provides living documentation
**Workflow benefits**:
- Clear next step (make test pass)
- Confidence when refactoring
- Prevents over-engineering
## Arrange-Act-Assert Pattern
### The AAA Pattern
Every test should follow this structure:
```typescript
test('user registration creates account and sends welcome email', async () => {
// ARRANGE - Set up test conditions
const userData = {
email: '[email protected]',
password: 'SecurePass123',
name: 'Test User',
};
const mockEmailService = jest.fn();
const userService = new UserService(mockEmailService);
// ACT - Execute the behavior being tested
const result = await userService.register(userData);
// ASSERT - Verify the outcome
expect(result.id).toBeDefined();
expect(result.email).toBe(userData.email);
expect(mockEmailService).toHaveBeenCalledWith({
to: userData.email,
subject: 'Welcome!',
template: 'welcome',
});
});
```
### Why AAA?
- **Clear structure**: Easy to understand what's being tested
- **Consistent**: All tests follow same pattern
- **Maintainable**: Easy to modify and debug
## Mocking Strategies
### When to Mock
**✅ DO mock**:
- External APIs
- Databases
- File system operations
- Time/dates
- Random number generators
- Network requests
- Third-party services
```typescript
// Mock external API
jest.mock('axios');
test('fetches user data from API', async () => {
const mockData = { id: 1, name: 'John' };
(axios.get as jest.Mock).mockResolvedValue({ data: mockData });
const user = await fetchUser(1);
expect(user).toEqual(mockData);
});
```
### When NOT to Mock
**❌ DON'T mock**:
- Pure functions (test them directly)
- Simple utility functions
- Domain logic
- Value objects
- Internal implementation details
```typescript
// ❌ BAD - Over-mocking
test('validates email', () => {
const validator = new EmailValidator();
jest.spyOn(validator, 'isValid').mockReturnValue(true);
expect(validator.isValid('[email protected]')).toBe(true);
// This test is useless - you're testing the mock, not the code
});
// ✅ GOOD - Test real implementation
test('validates email', () => {
const validator = new EmailValidator();
expect(validator.isValid('[email protected]')).toBe(true);
expect(validator.isValid('invalid')).toBe(false);
});
```
### Mocking Patterns
**Stub** (return predetermined values):
```typescript
const mockDatabase = {
findUser: jest.fn().mockResolvedValue({ id: 1, name: 'John' }),
saveUser: jest.fn().mockResolvedValue(true),
};
```
**Spy** (track calls, use real implementation):
```typescript
const emailService = new EmailService();
const sendSpy = jest.spyOn(emailService, 'send');
await emailService.send('[email protected]', 'Hello');
expect(sendSpy).toHaveBeenCalledTimes(1);
expect(sendSpy).toHaveBeenCalledWith('[email protected]', 'Hello');
```
**Fake** (lightweight implementation):
```typescript
class FakeDatabase {
private data = new Map();
async save(key: string, value: any) {
this.data.set(key, value);
}
async get(key: string) {
return this.data.get(key);
}
}
```
## Test Coverage Goals
### Coverage Metrics
**Line Coverage**: Percentage of code lines executed
- **Target**: 80-90% for critical paths
**Branch Coverage**: Percentage of if/else branches tested
- **Target**: 80%+ (more important than line coverage)
**Function Coverage**: Percentage of functions called
- **Target**: 90%+
**Statement Coverage**: Percentage of statements executed
- **Target**: 80%+
### Coverage Configuration
```json
// package.json
{
"jest": {
"collectCoverage": true,
"coverageThreshold": {
"global": {
"branches": 80,
"functions": 90,
"lines": 80,
"statements": 80
},
"./src/critical/": {
"branches": 95,
"functions": 95,
"lines": 95,
"statements": 95
}
},
"coveragePathIgnorePatterns": [
"/node_modules/",
"/tests/",
"/migrations/",
"/.config.ts$/"
]
}
}
```
### What to Prioritize
**High priority** (aim for 95%+ coverage):
- Business logic
- Security-critical code
- Payment/billing code
- Data validation
- Authentication/authorization
**Medium priority** (aim for 80%+ coverage):
- API endpoints
- Database queries
- Utility functions
- Error handling
**Low priority** (optional coverage):
- UI components (use integration tests instead)
- Configuration files
- Type definitions
- Third-party library wrappers
## Integration Testing
### Database Integration Tests
```typescript
import { PrismaClient } from '@prisma/client';
describe('UserRepository', () => {
let prisma: PrismaClient;
let repository: UserRepository;
beforeAll(async () => {
// Use test database
prisma = new PrismaClient({
datasources: { db: { url: process.env.TEST_DATABASE_URL } },
});
repository = new UserRepository(prisma);
});
beforeEach(async () => {
// Clean database before each test
await prisma.user.deleteMany();
});
afterAll(async () => {
await prisma.$disconnect();
});
test('creates user and retrieves by email', async () => {
// ARRANGE
const userData = {
email: '[email protected]',
name: 'Test User',
password: 'hashed_password',
};
// ACT
const created = await repository.create(userData);
const retrieved = await repository.findByEmail(userData.email);
// ASSERT
expect(retrieved).toBeDefined();
expect(retrieved?.id).toBe(created.id);
expect(retrieved?.email).toBe(userData.email);
});
});
```
### API Integration Tests
```typescript
import request from 'supertest';
import { app } from '../src/app';
describe('User API', () => {
test('POST /api/users creates user and returns 201', async () => {
const response = await request(app)
.post('/api/users')
.send({
email: '[email protected]',
Related in Cloud & DevOps
appbuilder-action-scaffolder
IncludedCreate, implement, deploy, and debug Adobe Runtime actions with consistent layout, validation, and error handling. Use this skill whenever the user needs to add actions to an App Builder project, understand action structure (params, response format, web/raw actions), configure actions in the manifest, use App Builder SDKs (State, Files, Events, database), deploy and invoke actions via CLI, debug action issues, or implement patterns such as webhook receivers, custom event providers, journaling consumers, large payload redirects, action sequence pipelines, and Asset Compute workers. Also trigger when users mention serverless functions in Adobe context, action logging, IMS authentication for actions, or cron-style scheduled actions.
orchestrating-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. Use this skill when the user needs a multi-step Data Cloud pipeline, cross-phase troubleshooting, or data space and data kit management. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase sf data360 workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching phase-specific skill), the task is STDM/session tracing/parquet telemetry (use observing-agentforce), standard CRM SOQL (use querying-soql), or Apex implementation (use generating-apex).
github-project-automation
IncludedAutomate GitHub repository setup with CI/CD workflows, issue templates, Dependabot, and CodeQL security scanning. Includes 12 production-tested workflows and prevents 18 errors: YAML syntax, action pinning, and configuration. Use when: setting up GitHub Actions CI/CD, creating issue/PR templates, enabling Dependabot or CodeQL scanning, deploying to Cloudflare Workers, implementing matrix testing, or troubleshooting YAML indentation, action version pinning, secrets syntax, runner versions, or CodeQL configuration. Keywords: github actions, github workflow, ci/cd, issue templates, pull request templates, dependabot, codeql, security scanning, yaml syntax, github automation, repository setup, workflow templates, github actions matrix, secrets management, branch protection, codeowners, github projects, continuous integration, continuous deployment, workflow syntax error, action version pinning, runner version, github context, yaml indentation error
sf-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase `sf data360` workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching sf-datacloud-* skill), the task is STDM/session tracing/parquet telemetry (use sf-ai-agentforce-observability), standard CRM SOQL (use sf-soql), or Apex implementation (use sf-apex).
fabric-cli
IncludedUse this skill for Fabric.so CLI workflows with the `fabric` terminal command: diagnose/install/login, search or browse a Fabric library, save notes/links/files, create folders, ask the Fabric AI assistant, manage tasks/workspaces, generate shell completion, check subscription usage, produce JSON output, and use Fabric as persistent agent memory. Do not use for Microsoft Fabric/Azure/Power BI `fab`, Daniel Miessler's Fabric framework, Python Fabric SSH, Fabric.js, or textile/fashion fabric.
lark
IncludedLark/Feishu CLI skills: lark-cli operations for docs, markdown, sheets, base, calendar, im, mail, task, okr, drive, wiki, slides, whiteboard, apps, approval, attendance, contact, vc, minutes, event. Use when the user needs to operate Lark/Feishu resources via lark-cli, send messages, manage documents, spreadsheets, calendars, tasks, OKRs, deploy web pages, or any Feishu/Lark workspace operations.