Testing Patterns
Maybern uses pytest for all testing. This guide covers testing patterns for APIs, services, selectors, and models.Test Organization
Tests live alongside the code they test:Testing Strategies
Unit Tests
Mock dependencies, test in isolation. Use for private services and selectors.
Integration Tests
Test with real dependencies. Use for public services.
Unit Testing with Mocks
Use@patch to mock dependencies and test in isolation:
API Testing
Mock the service layer when testing APIs:Factory Usage
Use factories to create test data:Factory Best Practices
Use .build() for In-Memory Objects
Use .build() for In-Memory Objects
When you need an object but don’t need it in the database:
Pass Objects, Not IDs
Pass Objects, Not IDs
When overriding foreign keys:
Avoid Duplicate Sub-Factories
Avoid Duplicate Sub-Factories
Ensure related factories share the same parent objects:
Use Traits for Common Scenarios
Use Traits for Common Scenarios
Integration Testing Public Services
Public services can be integration tested (no mocks):Testing Fixtures
Common fixtures available inconftest.py:
Test Naming Convention
Follow the Arrange-Act-Assert pattern with clear test names:Running Tests
Best Practices Summary
Unit Test Private, Integration Test Public
Unit Test Private, Integration Test Public
- Private services/selectors: Mock dependencies
- Public services: Test with real database
- APIs: Mock service layer
Use Factories Correctly
Use Factories Correctly
.build()for in-memory objects.create()for database objects- Pass objects, not IDs, for foreign keys
- Use traits for common scenarios
Follow AAA Pattern
Follow AAA Pattern
- Arrange: Set up test data and mocks
- Act: Call the function being tested
- Assert: Verify the results
Write Descriptive Test Names
Write Descriptive Test Names
Test names should describe:
- The scenario being tested
- The expected outcome
- Any important conditions