Skip to content

Testing

Roberto Cruz edited this page May 15, 2026 · 1 revision

Testing

Running the Test Suite

# Run all tests
uv run pytest

# Verbose output
uv run pytest -v

# Run a specific file
uv run pytest tests/test_person.py

# Run a specific test
uv run pytest tests/test_state.py::test_condition_onset

# Stop on first failure
uv run pytest -x

Coverage

# Terminal coverage report
uv run pytest --cov=synthea --cov-report=term-missing

# HTML report (open htmlcov/index.html)
uv run pytest --cov=synthea --cov-report=html

# Fail if coverage drops below 80%
uv run pytest --cov=synthea --cov-fail-under=80

Parallel Test Execution

# Auto-detect CPU count
uv run pytest -n auto

# Fixed number of workers
uv run pytest -n 4

Test Structure

tests/
├── test_person.py          # Person attributes and health record
├── test_state.py           # All state type implementations
├── test_generator.py       # Generator orchestration and stats
├── test_integration.py     # End-to-end generation + FHIR output
├── unit/                   # Fine-grained unit tests
│   ├── test_logic.py
│   ├── test_transition.py
│   └── test_config.py
└── integration/            # Slower full-pipeline tests
    ├── test_fhir_export.py
    └── test_csv_export.py

Writing Tests

# tests/test_my_module.py
import pytest
from synthea import Generator, GeneratorOptions


@pytest.fixture
def generator():
    opts = GeneratorOptions()
    opts.population_size = 1
    opts.seed = 42
    opts.threads = 1
    return Generator(opts)


def test_generates_one_patient(generator):
    generator.run()
    assert generator.stats["total_generated"] == 1


def test_fhir_output_exists(generator, tmp_path):
    from pathlib import Path
    generator.options.output_dir = str(tmp_path)
    generator.run()

    fhir_files = list((tmp_path / "fhir").glob("*.json"))
    # hospitalInformation + practitionerInformation + 1 patient = 3
    assert len(fhir_files) >= 1


def test_patient_has_conditions(generator):
    from synthea.world.person import Person
    person = Person(seed=42)
    person.init_health_record()
    generator._simulate_life(person)

    # At minimum a person should have recorded encounters
    assert len(person.health_record.encounters) > 0

Validate a Custom Module

# Check JSON syntax and required fields
uv run python -m synthea.validate_module resources/modules/my_module.json

Continuous Testing

# Watch for file changes and re-run (requires pytest-watch)
uv run ptw

# Use testmon to only rerun affected tests
uv run pytest --testmon

CI Configuration (GitHub Actions)

name: Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v3
        with:
          python-version: "3.11"
      - run: uv pip install -e ".[dev]"
      - run: uv run pytest --cov=synthea --cov-fail-under=80

Clone this wiki locally