Unit Testing
Test isolated business logic with fast, deterministic tests.
AAA Pattern (Arrange-Act-Assert)
describe('calculateDiscount', () => { test('applies 10% discount for orders over $100', () => { // Arrange const order = { items: [{ price: 150 }] };
// Act
const result = calculateDiscount(order);
// Assert
expect(result).toBe(15);
}); });
Test Isolation
describe('UserService', () => { let service: UserService; let mockRepo: MockRepository;
beforeEach(() => { // Fresh instances per test mockRepo = createMockRepository(); service = new UserService(mockRepo); });
afterEach(() => { // Clean up vi.clearAllMocks(); }); });
Coverage Targets
Area Target
Business logic 90%+
Critical paths 100%
New features 100%
Utilities 80%+
Parameterized Tests
describe('isValidEmail', () => { test.each([ ['test@example.com', true], ['invalid', false], ['@missing.com', false], ['user@domain.co.uk', true], ])('isValidEmail(%s) returns %s', (email, expected) => { expect(isValidEmail(email)).toBe(expected); }); });
Python Example
import pytest
class TestCalculateDiscount: def test_applies_discount_over_threshold(self): # Arrange order = Order(total=150)
# Act
discount = calculate_discount(order)
# Assert
assert discount == 15
@pytest.mark.parametrize("total,expected", [
(100, 0),
(101, 10.1),
(200, 20),
])
def test_discount_thresholds(self, total, expected):
order = Order(total=total)
assert calculate_discount(order) == expected
Fixture Scoping (2026 Best Practice)
import pytest
Function scope (default): Fresh instance per test - ISOLATED
@pytest.fixture(scope="function") def db_session(): """Each test gets clean database state.""" session = create_session() yield session session.rollback() # Cleanup
Module scope: Shared across all tests in file - EFFICIENT
@pytest.fixture(scope="module") def expensive_model(): """Load once per test file (expensive setup).""" return load_large_ml_model() # 5 seconds to load
Session scope: Shared across ALL tests - MOST EFFICIENT
@pytest.fixture(scope="session") def db_engine(): """Single connection pool for entire test run.""" engine = create_engine(TEST_DB_URL) Base.metadata.create_all(engine) yield engine Base.metadata.drop_all(engine)
When to use each scope:
Scope Use Case Example
function Isolated tests, mutable state db_session, mock objects
module Expensive setup, read-only ML model, compiled regex
session Very expensive, immutable DB engine, external service
Indirect Parametrization
Defer expensive setup from collection to runtime
@pytest.fixture def user(request): """Create user with different roles based on parameter.""" role = request.param # Receives value from parametrize return UserFactory(role=role)
@pytest.mark.parametrize("user", ["admin", "moderator", "viewer"], indirect=True) def test_permissions(user): """Test runs 3 times with different user roles.""" # user fixture is called with each role assert user.can_access("/dashboard") == (user.role in ["admin", "moderator"])
Combinatorial testing with stacked decorators
@pytest.mark.parametrize("role", ["admin", "user"]) @pytest.mark.parametrize("status", ["active", "suspended"]) def test_access_matrix(role, status): """Runs 4 tests: admin/active, admin/suspended, user/active, user/suspended""" user = User(role=role, status=status) expected = (role == "admin" and status == "active") assert user.can_modify() == expected
Key Decisions
Decision Recommendation
Framework Vitest (modern), Jest (mature), pytest
Execution < 100ms per test
Dependencies None (mock everything external)
Coverage tool c8, nyc, pytest-cov
Common Mistakes
-
Testing implementation, not behavior
-
Slow tests (external calls)
-
Shared state between tests
-
Over-mocking (testing mocks not code)
Related Skills
-
integration-testing
-
Testing interactions
-
msw-mocking
-
Network mocking
-
test-data-management
-
Fixtures and factories
Capability Details
pytest-patterns
Keywords: pytest, python, fixture, parametrize Solves:
-
Write pytest unit tests
-
Use fixtures effectively
-
Parametrize test cases
vitest-patterns
Keywords: vitest, jest, typescript, mock Solves:
-
Write Vitest unit tests
-
Mock dependencies
-
Test React components
orchestkit-strategy
Keywords: orchestkit, strategy, coverage, pyramid Solves:
-
OrchestKit test strategy example
-
Test coverage targets
-
Testing pyramid ratios
test-case-template
Keywords: template, test, structure, arrange Solves:
-
Test case template
-
Arrange-Act-Assert structure
-
Copy-paste test starter