ReleaseBoard has a comprehensive test suite with 1141 tests covering all layers of the architecture. This guide explains how to run tests, understand the test organization, and add new tests.
# All tests
pytest
# Verbose
pytest -v
# With coverage
pytest --cov=releaseboard --cov-report=term-missing
# Specific file
pytest tests/test_readiness_analysis.py
# Specific test
pytest tests/test_config.py::TestBranchPatternOverrides::test_layer_override_takes_precedenceNote: The full test suite contains 1223 tests. Run
pytest -qfor a compact summary orpytest -vfor detailed per-test output.
| File | Coverage |
|---|---|
test_branch_pattern.py |
Pattern resolution, regex matching, template validation |
test_config.py |
Schema validation, loading, env vars, three-tier overrides, per-layer root URL resolution |
test_readiness_analysis.py |
All readiness status paths (ready, missing, stale, invalid, error) |
test_staleness.py |
Staleness detection, freshness labels |
test_metrics.py |
Metrics aggregation, layer breakdown, attention sorting |
test_renderer.py |
HTML rendering, file output, theme attributes, chart data |
test_theme.py |
Theme resolution, color mappings |
test_integration.py |
End-to-end: config to analysis to rendering |
test_service.py |
AnalysisService pipeline, progress callbacks, cancellation |
test_state.py |
AppState management, three-tier config state, SSE subscribers |
| File | Coverage |
|---|---|
test_git_providers.py |
GitProvider abstraction, SmartGitProvider selection, default-branch fallback |
test_error_classification.py |
GitErrorKind enum, classify_git_error(), HTTP status mapping, placeholder detection |
test_config_ui.py |
Config drawer UI, form/JSON/effective tabs, validation scoping |
test_config_persistence.py |
Config loading, atomic save, backup creation, validation on save |
test_config_resilience.py |
Config resilience under edge cases, corrupt files, missing keys |
test_config_schema_layout.py |
Schema validation edge cases, effective value validation, layout rules |
test_config_save_compliance.py |
Config save compliance, backup rotation, file locking |
test_dashboard_ui.py |
Dashboard layout, toolbar, status bar, drag-and-drop, detail modal |
test_ui_dashboard_sections.py |
UI/UX interactions, inherited value display, branch pattern indicators |
test_github_public_repos.py |
Public GitHub repos, unauthenticated API access, enriched metadata |
test_provider_parsing_errors.py |
Provider-specific features, URL derivation, error parsing |
test_provider_url_ssl.py |
Git provider URL resolution, SSL handling |
test_api_discover_export.py |
Provider API interaction, discovery, export endpoints |
test_endpoint_lifecycle.py |
Analysis lifecycle state transitions, endpoint behavior |
test_output_templates.py |
Output rendering, template validation, export regressions |
test_security_headers_csrf.py |
Security headers, CSRF protection, CSP policies |
test_web_sse_health.py |
Web infrastructure, SSE streaming, health checks |
test_csp_defaults_caching.py |
CSP directives, default configuration, caching behavior |
test_i18n_sse_datetime.py |
Internationalization, SSE event formatting, datetime handling |
test_staleness_branding_schema.py |
Staleness detection, branding endpoints, schema validation |
test_milestone_labels_validation.py |
Milestone labels i18n, target year validation, order constraints |
test_header_buttons_url_focus.py |
Header company name, button styles, URL/slug field focus |
test_i18n.py |
Internationalization, locale loading |
test_release_calendar.py |
Release calendar utilities and validation |
test_release_pilot.py |
ReleasePilot integration adapter |
test_web.py |
FastAPI endpoints, API routes, SSE streaming |
test_web_calendar.py |
Web calendar endpoints |
| File | Coverage |
|---|---|
test_integration.py |
End-to-end: config to analysis to rendering |
All tests follow the GIVEN/WHEN/THEN pattern using docstring-based sections:
def test_nonexistent_path(self, tmp_path: Path):
"""GIVEN a path that does not exist."""
bad_path = str(tmp_path / "nonexistent")
"""WHEN inspecting the path."""
result = inspect_repo(bad_path)
"""THEN it is not a valid repo."""
assert result.is_valid_repo is False
assert "does not exist" in result.errorRules:
"""GIVEN ..."""is the method docstring with setup code directly below"""WHEN ..."""is a string literal with the action code directly below"""THEN ..."""is a string literal with assertions directly below- Every section must have code beneath it - no empty sections
- One blank line separates sections
- Each description ends with a period
Note: Class-level docstrings use the
"""Scenarios for ..."""format to describe the test group.
Shared fixtures in conftest.py:
sample_config- fullAppConfigwith 3 layers and 5 repossample_config_dict- raw JSON dict for schema testsrecent_branch_info-BranchInfowith today's datestale_branch_info-BranchInfowith old datetmp_config_file- config written to temp file
When adding new features:
- Add tests for the behavior, not the implementation
- Follow the GIVEN/WHEN/THEN pattern for every test method
- Use the existing fixtures where possible
- Prefer fewer, stronger tests over many trivial ones
- Integration tests go in
test_integration.py
Note: Use descriptive test method names that convey intent. Naming convention:
test_<expected_outcome>_when_<condition>.