بنقرة واحدة
testing-strategy
Test naming conventions, fixture patterns, mocking strategies, and coverage thresholds by stage
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Test naming conventions, fixture patterns, mocking strategies, and coverage thresholds by stage
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Structured web research methodology for market analysis, competitor research, and technology evaluation. Ensures research uses live web data with source citations and confidence tags.
Mermaid diagram templates for solution architecture, service communication, C4 Context/Container, data flow, agent flow, deployment, and sequence diagrams. Use when generating architecture diagrams.
Solution Design Language (SDL) specification — schema, validation, normalization, and generation rules
Core methodology for analysing requirements, building system manifests, and generating architecture deliverables. Use when planning or designing any software architecture.
Extract and render all Mermaid diagrams from architecture blueprints to PNG images. Creates a diagrams/ folder with high-quality images ready for presentations and documentation.
Convert architecture documents (blueprints, stakeholder presentations) from Markdown to professionally formatted Word (.docx) files. Applies corporate styling, embeds PNG diagrams, and creates presentation-ready documents.
| name | Testing Strategy |
| description | Test naming conventions, fixture patterns, mocking strategies, and coverage thresholds by stage |
Covers unit, integration, and e2e test patterns for all supported frameworks.
src/services/user.ts → src/services/__tests__/user.test.ts (Jest/Vitest)src/services/user.ts → src/services/test_user.py (pytest)tests/ directory at project root
tests/integration/auth.test.tstests/integration/database.test.tse2e/ or tests/e2e/ directory
e2e/flows/login.test.tse2e/flows/checkout.test.ts<module>.test.ts or <module>_test.py<feature>.integration.test.ts or test_<feature>.py<flow>.e2e.test.ts or test_<flow>_e2e.pyAll tests MUST follow AAA pattern:
describe('UserService', () => {
describe('createUser', () => {
it('should create a user with valid email and name', () => {
// ARRANGE: Setup test data, mocks, fixtures
const email = 'alice@example.com';
const name = 'Alice Chen';
// ACT: Call the function under test
const user = service.createUser(email, name);
// ASSERT: Verify the result
expect(user.email).toBe(email);
expect(user.name).toBe(name);
expect(user.id).toBeDefined();
});
});
});
Golden rule: One logical assertion per test (one reason to fail).
❌ BAD:
it('works', () => { ... });
it('user creation 1', () => { ... });
✅ GOOD:
it('should create a user with valid email and return user object with id', () => { ... });
it('should reject email without @ symbol', () => { ... });
it('should hash password before storing in database', () => { ... });
Pattern: should [what happens] [given conditions if not obvious]
// jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src', '<rootDir>/tests'],
testMatch: ['**/__tests__/**/*.ts', '**/*.test.ts'],
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
'!src/index.ts'
],
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80
}
}
};
// tsconfig.test.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react",
"types": ["jest", "node"]
}
}
# pytest.ini
[pytest]
testpaths = tests
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_*
addopts = --verbose --strict-markers
markers =
unit: unit tests
integration: integration tests
slow: slow running tests
# conftest.py — shared fixtures
import pytest
@pytest.fixture
def sample_user():
return {'id': 1, 'email': 'test@example.com', 'name': 'Test User'}
// *_test.go convention
package user
import "testing"
func TestCreateUser(t *testing.T) {
user := CreateUser("alice@example.com", "Alice")
if user.Email != "alice@example.com" {
t.Errorf("expected %q, got %q", "alice@example.com", user.Email)
}
}
public class UserServiceTests
{
[Fact]
public void CreateUser_WithValidEmail_ReturnsUserWithId()
{
// Arrange
var service = new UserService();
// Act
var user = service.CreateUser("alice@example.com", "Alice");
// Assert
Assert.NotNull(user.Id);
Assert.Equal("alice@example.com", user.Email);
}
}
Use in-memory database for unit tests when possible:
// jest.config.js for Node backend
module.exports = {
setupFilesAfterEnv: ['<rootDir>/tests/setup.ts']
};
// tests/setup.ts
import { PrismaClient } from '@prisma/client';
beforeAll(async () => {
// Point to test database
process.env.DATABASE_URL = 'file:./test.db';
await prisma.$executeRawUnsafe('PRAGMA foreign_keys = OFF');
});
afterEach(async () => {
// Clean up between tests
await prisma.$queryRaw`DELETE FROM "User"`;
await prisma.$queryRaw`DELETE FROM "Post"`;
});
afterAll(async () => {
await prisma.$disconnect();
});
Mock HTTP calls, external APIs, payment gateways:
// jest.mock for modules
jest.mock('../lib/stripe', () => ({
createPayment: jest.fn().mockResolvedValue({ id: 'pay_123', status: 'succeeded' })
}));
// Manual mock for fetch
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ data: [] })
})
);
Use actual test database for integration tests:
// tests/integration/setup.ts
beforeAll(async () => {
// Spin up test PostgreSQL via docker-compose.test.yml
process.env.DATABASE_URL = 'postgresql://test:test@localhost:5433/test_db';
await prisma.$executeRawUnsafe('CREATE SCHEMA IF NOT EXISTS tests');
});
afterAll(async () => {
await prisma.$executeRawUnsafe('DROP SCHEMA tests CASCADE');
});
Rule: If a test needs the database to run, it's an integration test, not a unit test. Don't mock the database for integration tests.
// tests/fixtures/user.fixtures.ts
export const validUser = {
email: 'alice@example.com',
name: 'Alice Chen',
password: 'SecurePass123!'
};
export const adminUser = {
...validUser,
role: 'admin'
};
export const inactiveUser = {
...validUser,
status: 'inactive'
};
// In test file
import { validUser, adminUser } from './fixtures/user.fixtures';
it('should allow admin to create users', () => {
const created = service.createUser(validUser, { createdBy: adminUser });
expect(created.createdBy).toBe(adminUser.id);
});
// tests/factories/user.factory.ts
class UserFactory {
static async create(overrides = {}) {
const defaults = {
email: `user-${Date.now()}@example.com`,
name: 'Test User',
role: 'user'
};
return prisma.user.create({
data: { ...defaults, ...overrides }
});
}
static async createMany(count, overrides = {}) {
return Promise.all(
Array.from({ length: count }).map(() => this.create(overrides))
);
}
}
// In test
const users = await UserFactory.createMany(10, { role: 'admin' });
expect(users).toHaveLength(10);
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:unit": "jest --testPathPattern=__tests__",
"test:integration": "jest --testPathPattern=integration",
"test:e2e": "playwright test"
}
}
pytest # all tests
pytest -m unit # unit tests only
pytest -m integration # integration tests
pytest -v --cov=src # with coverage
go test ./... # all tests
go test -cover ./... # with coverage
go test -run TestCreateUser # specific test
// Always return promise or use async/await
it('should fetch user by id', async () => {
const user = await service.getUserById(1);
expect(user.id).toBe(1);
});
// Expect promises to resolve/reject
it('should reject invalid id', async () => {
await expect(service.getUserById(-1)).rejects.toThrow('Invalid ID');
});
import pytest
@pytest.mark.asyncio
async def test_fetch_user():
user = await service.get_user(1)
assert user.id == 1
# Or use sync wrapper
from asyncio import run
def test_sync_wrapper():
user = run(service.get_user(1))
assert user.id == 1
// Jest
it.skip('should handle network timeout', () => {
// Re-enable after fixing flakiness
});
// pytest
@pytest.mark.skip(reason="flaky, TODO: fix race condition")
def test_concurrent_updates():
pass
// jest.config.js
module.exports = {
testTimeout: 30000 // 30s for slow tests
};
// In test
jest.setTimeout(5000); // override for this test
it.todo('should support bulk user import');
- name: Run Tests
run: npm test -- --coverage
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
- name: Check Coverage
run: |
COVERAGE=$(npm test -- --coverage | grep Lines | awk '{print $NF}' | sed 's/%//')
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "Coverage $COVERAGE% below threshold 80%"
exit 1
fi