End-to-End Testing

July 7, 2026 · View on GitHub

tests/test_e2e_new_modules.py

End-to-end integration tests for the 20 new modules added in March 2026. These tests verify that modules work together as integrated pipelines, not just in isolation.


Running the Tests

# All e2e tests
pytest tests/test_e2e_new_modules.py -v

# Specific pipeline
pytest tests/test_e2e_new_modules.py -v -k "TestOpenSystemPipeline"

# With timing
pytest tests/test_e2e_new_modules.py -v --tb=short --durations=10

# All tests (unit + e2e)
pytest tests/ -v -m "not slow and not hardware"

Test Structure

Test classPipelineModules exercisedTests
TestOpenSystemPipelineLindblad ↔ MCWF agreementlindblad, tensor_jump, ancilla_lindblad4
TestSymmetryPipelineZ₂ → U(1) → sparsesymmetry_sectors, magnetisation_sectors, translation_symmetry, sparse_hamiltonian8
TestMultiPlatformPipelineCompile → exportxy_compiler, circuit_export, ancilla_lindblad4
TestVariationalPipelineNQS + param-shift + VQEnqs_ansatz, param_shift, gpu_batch_vqe, sparse_hamiltonian, contraction_optimiser5
TestHardwareReadyPipelineAncilla → stats → exportancilla_lindblad, lindblad, tensor_jump2
TestFullPipelineRecommend → solve → exportbackend_selector, circuit_export, ancilla_lindblad, magnetisation_sectors, sparse_hamiltonian4
TestBackendDispatchIntegrationBackend switchingbackend_dispatch, backend_selector3
TestPluginRegistryIntegrationRegistry → runnerplugin_registry2
TestCrossModuleConsistencyShared computation checksAll ED + sparse + open-system modules6
Total20 modules38

Pipeline Descriptions

Pipeline 1: Open-System Kuramoto (Lindblad ↔ MCWF)

Modules: lindblad.py, tensor_jump.py, ancilla_lindblad.py

What is tested:

  • Lindblad density matrix R(T) and MCWF ensemble R(T) agree within statistical error for the same physical parameters
  • Zero-dissipation case produces identical results (no jumps)
  • Ancilla circuit compiles correctly for the same system
  • All three open-system methods produce valid output

Physical invariant: Lindblad is exact; MCWF converges to Lindblad in the limit of infinite trajectories. Agreement within ±0.15\pm 0.15 for 200 trajectories at n=2n=2 is expected.

Pipeline 2: Scaling with Symmetry (Z₂ → U(1) → Sparse)

Modules: symmetry_sectors.py, magnetisation_sectors.py, translation_symmetry.py, sparse_hamiltonian.py

What is tested:

  • Z₂ sector eigenvalues reconstruct the full spectrum exactly
  • U(1) sector eigenvalues reconstruct the full spectrum exactly
  • Z₂ and U(1) find the same ground energy
  • Sparse eigsh matches dense eigh
  • Sparse within U(1) sector matches dense U(1) sector
  • All four methods agree at n=4,6,8n = 4, 6, 8
  • Memory estimates are consistent (full > Z₂ > U(1))
  • Translation symmetry ground within full spectrum

Physical invariant: All methods diagonalise the same Hamiltonian. Ground energy must be identical (up to numerical precision). The only difference is computational cost.

Pipeline 3: Multi-Platform Execution (Compile → Export)

Modules: xy_compiler.py, circuit_export.py, ancilla_lindblad.py

What is tested:

  • XY-compiled circuit exports to valid QASM
  • XY compiler produces circuits with measurable depth
  • All export formats (Qiskit, QASM, Quil) are consistent
  • Ancilla circuit is QASM-exportable

Physical invariant: All formats represent the same unitary evolution. Format-specific syntax is validated (OPENQASM header, DECLARE in Quil).

Pipeline 4: Variational Ground State (NQS + Param-Shift + Batch VQE)

Modules: nqs_ansatz.py, param_shift.py, gpu_batch_vqe.py, sparse_hamiltonian.py, contraction_optimiser.py

What is tested:

  • RBM VMC energy within 50% of exact (conservative bound — VMC is not guaranteed to converge for all initialisations)
  • Parameter-shift VQE reduces energy over iterations
  • Batch VQE scan finds energy below mean random
  • NQS energy is a variational upper bound (≥ exact)
  • Contraction optimiser gives same results as np.einsum

Physical invariant: Variational principle — VMC/VQE energy \geq exact ground energy. The gap depends on ansatz expressibility and optimisation.

Pipeline 5: Hardware-Ready Open-System Circuit

Modules: ancilla_lindblad.py, lindblad.py, tensor_jump.py

What is tested:

  • Build circuit → check stats → export to QASM (full workflow)
  • All three open-system methods produce valid output for same system

Physical invariant: Circuit should have n+1n+1 qubits, non-zero resets, and be exportable.

Pipeline 6: Full Auto-Solve Pipeline

Modules: backend_selector.py, circuit_export.py, ancilla_lindblad.py, magnetisation_sectors.py, sparse_hamiltonian.py

What is tested:

  • recommend_backendauto_solve consistency
  • Solve → export for same system
  • Solve open-system → build ancilla circuit
  • U(1) sector → sparse eigsh → level spacing analysis

Physical invariant: auto_solve should use the backend recommended by recommend_backend. Ground energy should be negative for the XY model. Level-spacing ratio should be between 0.2 and 0.7 (Poisson to GOE range).

Pipeline 7: Backend Dispatch

Modules: backend_dispatch.py, backend_selector.py

What is tested:

  • Setting numpy backend then solving works
  • All available backends are settable
  • to_numpy(from_numpy(x)) roundtrip preserves data

Pipeline 8: Plugin Registry

Modules: plugin_registry.py

What is tested:

  • Qiskit runner from registry produces valid runner
  • Custom backend registration and invocation

Cross-Module Consistency Checks

The TestCrossModuleConsistency class verifies shared computation invariants across multiple modules:

TestInvariant
test_sparse_hermiticityH=HH = H^\dagger
test_sparse_vs_dense_matrixSparse and dense Hamiltonians are identical
test_sparsity_stats_consistentStats match actual matrix properties
test_lindblad_order_parameter_bounded$0 \leq R(t) \leq 1$
test_mcwf_std_decreases_with_trajectoriesMore trajectories → less noise
test_all_ed_methods_agreeFull/Z₂/U(1)/sparse give same E0E_0 at n=4,6,8n = 4, 6, 8

Module Coverage Matrix

Each row is a test class; columns are the 20 modules. ✓ = directly tested.

ModuleOpenSymmMultiVarHWFullDispPlugCross
lindblad
tensor_jump
ancilla_lindblad
symmetry_sectors
magnetisation_sectors
translation_symmetry
sparse_hamiltonian
mps_evolution
contraction_optimiser
nqs_ansatz
jax_nqs
mitiq_integration
param_shift
xy_compiler
circuit_export
backend_selector
backend_dispatch
plugin_registry
gpu_batch_vqe

Note: mps_evolution, jax_nqs, and mitiq_integration require optional dependencies (quimb, JAX, Mitiq) and are tested in their respective unit test files (test_mps_evolution.py, test_batch3_modules.py, test_mitiq_integration.py). The e2e tests avoid optional dependencies to ensure they run on the CI matrix without extras.


Adding New E2E Tests

When adding new cross-module functionality:

  1. Identify the pipeline (which modules interact)
  2. Write a test that exercises the full pipeline, not individual functions
  3. Assert on physical invariants (energy bounds, conservation laws, consistency between methods) rather than implementation details
  4. Use _system(n) helper for standard test systems
  5. Keep systems small (n8n \leq 8) for speed — e2e tests should complete in seconds, not minutes

See Also