Skip to main content
testing-strategy Test naming conventions, fixture patterns, mocking strategies, and coverage thresholds by stage
الانتقال إلى التثبيت سوق المهارات اكتشف واستكشف مهارات الذكاء الاصطناعي التي بناها المجتمع.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
نسخ Promptعرض تفاصيل Prompt يتجاوز الأمر المباشر Prompt المخصّص للمراجعة. افحص المصدر قبل تشغيله.
npx skills add https://github.com/navraj007in/architecture-cowork-plugin --skill testing-strategyيبقى الأمر في سطر واحد. مرّر أفقيًا لمراجعته كاملًا قبل النسخ.
تفضّل نسخة محلية؟ نزّل الملفات المتاحة حاليًا لدى SkillsMP.
تحميل Zip جاري التحميل... SOC
استنادا إلى تصنيف SOC المهني
name testing-strategy description Test naming conventions, fixture patterns, mocking strategies, and coverage thresholds by stage
Testing Strategy Skill
Covers unit, integration, and e2e test patterns for all supported frameworks.
Test File Organization
Folder Structure
Unit tests: co-locate with source files
src/services/user.ts → src/services/__tests__/user.test.ts (Jest/Vitest)
src/services/user.ts → src/services/test_user.py (pytest)
Integration tests: separate tests/ directory at project root
tests/integration/auth.test.ts
tests/integration/database.test.ts
E2E tests: separate e2e/ or tests/e2e/ directory
e2e/flows/login.test.ts
e2e/flows/checkout.test.ts
File Naming Convention
Unit: <module>.test.ts or <module>_test.py
Integration: <feature>.integration.test.ts or test_<feature>.py
E2E: <flow>.e2e.test.ts or test_<flow>_e2e.py
Test Structure: Arrange-Act-Assert
All tests MUST follow AAA pattern:
describe ('UserService' , () => {
describe ( , {
( , {
email = ;
name = ;
user = service. (email, name);
(user. ). (email);
(user. ). (name);
(user. ). ();
});
});
});
'createUser'
() =>
it
'should create a user with valid email and name'
() =>
const
'alice@example.com'
const
'Alice Chen'
const
createUser
expect
email
toBe
expect
name
toBe
expect
id
toBeDefined
Golden rule: One logical assertion per test (one reason to fail).
Test Naming: Descriptive, Not Clever it ('works' , () => { ... });
it ('user creation 1' , () => { ... });
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]
Framework-Specific Setup
Node.js / TypeScript (Jest / Vitest)
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
}
}
};
{
"extends" : "./tsconfig.json" ,
"compilerOptions" : {
"jsx" : "react" ,
"types" : ["jest" , "node" ]
}
}
Python (pytest)
[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
import pytest
@pytest.fixture
def sample_user ():
return {'id' : 1 , 'email' : 'test@example.com' , 'name' : 'Test User' }
Go (standard testing)
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)
}
}
.NET (xUnit) public class UserServiceTests
{
[Fact ]
public void CreateUser_WithValidEmail_ReturnsUserWithId ()
{
var service = new UserService();
var user = service.CreateUser("alice@example.com" , "Alice" );
Assert.NotNull(user.Id);
Assert.Equal("alice@example.com" , user.Email);
}
}
Mocking Strategy
Database Mocks (Unit Tests) Use in-memory database for unit tests when possible:
module .exports = {
setupFilesAfterEnv : ['<rootDir>/tests/setup.ts' ]
};
import { PrismaClient } from '@prisma/client' ;
beforeAll (async () => {
process.env .DATABASE_URL = 'file:./test.db' ;
await prisma.$executeRawUnsafe('PRAGMA foreign_keys = OFF' );
});
afterEach (async () => {
await prisma.$queryRaw `DELETE FROM "User"` ;
await prisma.$queryRaw `DELETE FROM "Post"` ;
});
afterAll (async () => {
await prisma.$disconnect();
});
External Service Mocks (Unit Tests) Mock HTTP calls, external APIs, payment gateways:
jest.mock ('../lib/stripe' , () => ({
createPayment : jest.fn ().mockResolvedValue ({ id : 'pay_123' , status : 'succeeded' })
}));
global .fetch = jest.fn (() =>
Promise .resolve ({
json : () => Promise .resolve ({ data : [] })
})
);
Real Database (Integration Tests) Use actual test database for integration tests:
beforeAll (async () => {
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.
Fixture Patterns
Shared Fixtures (Reusable Test Data)
export const validUser = {
email : 'alice@example.com' ,
name : 'Alice Chen' ,
password : 'SecurePass123!'
};
export const adminUser = {
...validUser,
role : 'admin'
};
export const inactiveUser = {
...validUser,
status : 'inactive'
};
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 );
});
Factory Pattern (Dynamic Test Data)
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))
);
}
}
const users = await UserFactory .createMany (10 , { role : 'admin' });
expect (users).toHaveLength (10 );
Coverage Thresholds by Stage
MVP Stage
Unit tests: ≥ 70% coverage (critical paths only)
Integration tests: ≥ 5 per service (authentication, CRUD, error cases)
E2E tests: ≥ 2 per major flow (happy path + error case)
Requirement: Tests must run in CI before merge
Growth Stage
Unit tests: ≥ 80% coverage (all public APIs)
Integration tests: ≥ 10 per service (edge cases, race conditions)
E2E tests: ≥ 5 per major flow (happy path, errors, edge cases)
Requirement: Failed tests block merge, coverage reports published
Enterprise Stage
Unit tests: ≥ 85% coverage (all code paths including errors)
Integration tests: ≥ 15 per service + contract tests
E2E tests: ≥ 10 per major flow + performance tests
Requirement: Coverage must improve or stay same; no regression allowed
Test Execution
NPM Script Convention {
"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"
}
}
Python Convention pytest
pytest -m unit
pytest -m integration
pytest -v --cov=src
Go Convention go test ./...
go test -cover ./...
go test -run TestCreateUser
Async / Await Testing
TypeScript (Jest)
it ('should fetch user by id' , async () => {
const user = await service.getUserById (1 );
expect (user.id ).toBe (1 );
});
it ('should reject invalid id' , async () => {
await expect (service.getUserById (-1 )).rejects .toThrow ('Invalid ID' );
});
Python (pytest) import pytest
@pytest.mark.asyncio
async def test_fetch_user ():
user = await service.get_user(1 )
assert user.id == 1
from asyncio import run
def test_sync_wrapper ():
user = run(service.get_user(1 ))
assert user.id == 1
Skip & Mark Patterns
Skip Flaky Tests
it.skip ('should handle network timeout' , () => {
});
@pytest .mark .skip (reason="flaky, TODO: fix race condition" )
def test_concurrent_updates ():
pass
Mark Slow Tests
module .exports = {
testTimeout : 30000
};
jest.setTimeout (5000 );
Mark as WIP (Work in Progress) it.todo ('should support bulk user import' );
CI/CD Integration
GitHub Actions - name: Run Tests
run: npm test -- --coverage
- name: Upload Coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
Fail on Coverage Drop - 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
Best Practices Checklist
✓ Each test file tests ONE class/module
✓ Each test method tests ONE behavior
✓ Test names describe the BEHAVIOR, not the method
✓ AAA structure (Arrange, Act, Assert)
✓ No test interdependencies (tests can run in any order)
✓ Mock external dependencies (APIs, databases, file system)
✓ Use real database for integration tests only
✓ Clean up after each test (teardown)
✓ Fixtures for reusable test data
✓ Factories for dynamic test data generation
✓ Timeouts for async tests
✓ Descriptive assertion messages
✓ One assertion per test when possible (one reason to fail)
✓ Avoid testing private implementation details
✓ Test behavior from the outside (black box)