Testing Guide
CuBIE uses pytest with several custom markers and conventions.
Running Tests
# Full suite (requires CUDA GPU)
python -m pytest
# CPU-only tests (CUDASIM mode)
export NUMBA_ENABLE_CUDASIM=1
python -m pytest -m "not nocudasim and not cupy"
# Specific module
python -m pytest tests/integrators/
# Specific test pattern
python -m pytest -k test_solver
Test Markers
nocudasimTest requires a real GPU; skip in CUDASIM mode.
cupyTest requires CuPy; skip if not installed.
slowLong-running test; useful with
-m "not slow"for quick iterations.sim_onlyTest only runs in CUDASIM mode.
specific_algosTest targets a specific algorithm and may be skipped in broad sweeps.
CUDASIM Mode
Setting NUMBA_ENABLE_CUDASIM=1 before import causes Numba to emulate
CUDA on the CPU. CI pipelines without GPUs use this mode. CUDASIM is
single-threaded and much slower than GPU execution, so keep CUDASIM-
compatible tests lightweight.
Instrumented Test Copies
tests/integrators/algorithms/instrumented/ contains copies of
algorithm device functions with added logging. These are used to verify
internal step behaviour (stage values, error estimates, etc.).
Important
When you change a source algorithm, replicate the change in its instrumented copy. The instrumented tests will fail if the two diverge.
Fixture Patterns
tests/conftest.py provides shared fixtures for ODE systems, solver
instances, and common parameter sets. Prefer using these fixtures over
constructing test objects manually.
Key fixtures include pre-built ODE systems (Lotka–Volterra, van der Pol, linear test systems) and solver factories parameterised by algorithm.
Philosophy
Failing tests are good. Tests should assert intended behaviour. If a test fails, fix the code, not the test (unless the test itself is wrong).
Prefer real objects over mocks. Use actual CuBIE objects and real (small) ODE systems. Never patch
is_devicechecks or CUDA availability.Never mark tests ``xfail`` or use
importorskipto hide failures.