Skip to content

Testing

Pytest collection is configured in the root pyproject.toml. There is no testpaths setting, so pytest from the repo root walks the tree:

  • Files named test_*.py. Pytest's default also collects *_test.py; don't use that name here.
  • Classes named Test* (pytest default). Some modules use classes, some only module-level functions.
  • Functions and methods named test_* (pytest default), including async def test_*.

Same test filename in different folders is fine (several test_application.py files exist). Root pyproject.toml already sets --import-mode=importlib so pytest keeps them separate. Do not remove that flag.

A test_*.py next to the code it validates is collected with no CI change. The root pyproject.toml skips parity_check, parity_check_v2, baseline_fastvideo, and baseline_lightx2v via norecursedirs.

Every test function must be marked with exactly one CI tier marker. A pytest plugin (flashdreams._pytest_plugins.marker_enforcement) enforces this at collection time -- tests without a marker are rejected, and tests with both ci_cpu and ci_gpu are rejected.

Marker When to use CI runner
@pytest.mark.ci_cpu Pure CPU logic, no GPU or libGL needed CPU runner
@pytest.mark.ci_gpu Needs CUDA, libGL, or transitive cv2 GPU runner (RTX Pro 6000)
@pytest.mark.manual Heavy (OOM risk), flaky, needs credentials or large downloads Not run in CI

Use a module-level pytestmark when every test in a file shares the same marker:

import pytest

pytestmark = pytest.mark.ci_cpu

Use per-function markers when tests in the same file have different tiers:

@pytest.mark.ci_cpu
def test_basic_math(): ...

@pytest.mark.ci_gpu
def test_cudagraph_path(): ...

Running tests locally:

uv run pytest -m ci_cpu          # CPU-safe tests only
uv run pytest -m ci_gpu          # GPU tests only (needs CUDA)
uv run pytest -m "not manual"    # everything that runs in CI
uv run pytest                    # all tests including manual

For local and Docker test-runner scripts, see tests/README.md.