Testing
Canon uses pytest for backend tests. Tests mirror the src/ directory structure.
Running Tests
bash
# Run all tests
make test
# Verbose output
make test-backend-v
# With coverage
make test-cov
# Run a specific test file
uv run pytest tests/test_parser.py
# Run a specific test
uv run pytest tests/test_parser.py::test_parse_frontmatter -vTest Structure
tests/
├── test_parser.py # Spec parser tests
├── test_writer.py # Spec writer tests
├── test_analyzer.py # Agent analyzer tests
├── test_prompts.py # Prompt builder tests
├── test_config.py # Config parser tests
├── test_sync.py # Ticket sync tests
├── test_verify.py # Webhook signature tests
├── test_spec_utils.py # Spec utility tests
└── ...Writing Tests
Conventions
- Test files are named
test_<module>.py - Test functions are named
test_<behavior> - Use pytest fixtures for shared setup
- Use
unittest.mock.patchorpytest-mockfor mocking external calls
Example
python
import pytest
from canon.parser.parse import parse_spec
def test_parse_frontmatter():
content = """---
title: "Test Spec"
status: draft
owner: test-user
---
# Test Spec
## 1. Background
Some background text.
"""
doc = parse_spec(content)
assert doc.title == "Test Spec"
assert doc.status == "draft"
assert doc.owner == "test-user"
assert len(doc.sections) == 1
def test_parse_acceptance_criteria():
content = """---
title: "Test"
status: draft
---
# Test
## 1. Feature
### Acceptance Criteria
- [ ] First criterion
- [x] Second criterion
- [ ] Third criterion
"""
doc = parse_spec(content)
section = doc.sections[0]
assert len(section.acceptance_criteria) == 3
assert section.acceptance_criteria[0].checked is False
assert section.acceptance_criteria[1].checked is TrueMocking External Services
Tests should not make real API calls. Mock external services:
python
from unittest.mock import AsyncMock, patch
@patch("canon.agent.client.ClaudeClient.analyze")
async def test_pr_analysis(mock_analyze):
mock_analyze.return_value = {
"summary": "Test summary",
"specReferences": [],
"discrepancies": [],
"docUpdates": [],
"realizations": [],
}
# ... test analysis pipelineFrontend Tests
bash
# Type checking (acts as a basic validation)
make test-frontend
# E2E tests (requires Playwright)
make test-e2e