Skip to content

test: parametrized engine contract test suite#141

Merged
ericchansen merged 3 commits intomasterfrom
refactor/engine-contract-tests
Mar 23, 2026
Merged

test: parametrized engine contract test suite#141
ericchansen merged 3 commits intomasterfrom
refactor/engine-contract-tests

Conversation

@ericchansen
Copy link
Owner

Summary

Adds a parametrized contract test suite that verifies every available MM engine satisfies the MMEngine ABC contract. Uses the engine registry from #134 to discover engines at collection time — new engines automatically get tested when they register.

What's tested

13 contract tests × N available engines (currently 3: OpenMM, JAX, JAX-MD):

Category Tests
Metadata name returns non-empty string, is_available() is True, supported_functional_forms() non-empty
Energy Returns float, near zero at equilibrium, increases when displaced
Hessian Shape is (3N, 3N), symmetric
Frequencies Returns list/array, count equals 3N
Minimize Returns tuple with 3+ elements, lowers energy, water molecule (medium tier)

Duplicate removal

Removed 6 tests from individual backend files that were exact duplicates of contract behavior:

  • test_jax_backend.py: test_is_available, test_hessian_shape, test_hessian_symmetric, test_frequencies_count
  • test_jax_md_backend.py: test_is_available, test_hessian_shape, test_hessian_symmetric

Kept all engine-specific extended tests (near-zero translation modes, analytical gradients, cross-engine parity, optimizer integration).

Other changes

  • mm/__init__.py: Added JaxMDEngine export, simplified try/except pattern (removed _HAS_JAX_ENGINE flag)

Test results

467 passed, 86 skipped (36 new contract tests, 6 duplicates removed → net +30)

Closes #139

Copilot AI review requested due to automatic review settings March 23, 2026 21:48
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a parametrized integration “contract” test suite to ensure all registered MM engines conform to the MMEngine interface and basic behavioral expectations, while removing duplicated per-engine tests.

Changes:

  • Added test/integration/test_engine_contract.py to run a shared contract suite across all available MM engines discovered via the registry.
  • Removed duplicated availability/Hessian/frequency-count tests from JAX and JAX-MD integration suites.
  • Updated q2mm/backends/mm/__init__.py exports to include JaxMDEngine and simplified optional import handling.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
test/integration/test_engine_contract.py New parametrized contract tests for MM engines using registry discovery.
test/integration/test_jax_backend.py Removes tests now covered by the shared contract suite.
test/integration/test_jax_md_backend.py Removes tests now covered by the shared contract suite.
q2mm/backends/mm/init.py Exports JaxMDEngine and adjusts __all__ population logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ericchansen ericchansen force-pushed the refactor/engine-contract-tests branch from c8f96e9 to 4d90dd9 Compare March 23, 2026 22:07
Copilot AI review requested due to automatic review settings March 23, 2026 22:10
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Create test/integration/test_engine_contract.py with 30+ contract tests
that run against every registered MM engine (jax, jax-md, openmm, tinker).
Tests cover metadata, bond/angle/vdw energy, analytical gradients, Hessian,
frequencies, minimization, and real-molecule (SN2) validation.

Gut per-engine test files to keep only truly engine-specific tests:
- JAX: known-value energy, handle/context reuse, _build_vdw_pairs, optimizer
- JAX-MD: LJ numeric formula, cross-engine parity, energy_breakdown, optimizer
- OpenMM: MM3 formula checks, context reuse, Tinker parity, Seminario pipeline
- Tinker: file-path API, SN2 imaginary frequencies

Import all engine modules unconditionally in mm/__init__.py (modules guard
their own deps). Add type hints to all test function arguments.

Closes #139

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 23, 2026 22:31
@ericchansen ericchansen force-pushed the refactor/engine-contract-tests branch from 8e46980 to 23d73bd Compare March 23, 2026 22:31
- Use PEP 562 __getattr__ lazy loading for JaxEngine/JaxMDEngine in
  mm/__init__.py so importing the package doesn't trigger JAX x64
  config as a side effect
- Make _functional_form() handle arbitrary engine functional forms
  instead of hard-coding harmonic/mm3 fallback

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Skip entire contract module when no MM engines are available
- Make engine/engine_name fixtures module-scoped to avoid repeated
  instantiation and JIT compilation overhead

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Owner Author

@ericchansen ericchansen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both items addressed in d16d514:

  1. Empty _AVAILABLE skip — Added pytest.skip("no MM engines available", allow_module_level=True) when _AVAILABLE is empty. The module now skips cleanly instead of erroring at collection time.

  2. Module-scope fixtures — Changed both engine_name and engine fixtures to scope="module". Each engine is instantiated once per module, avoiding repeated JIT compilation overhead for JAX/JAX-MD.

@ericchansen ericchansen merged commit 1c24d4b into master Mar 23, 2026
11 checks passed
@ericchansen ericchansen deleted the refactor/engine-contract-tests branch March 23, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: Parametrized engine contract test suite

2 participants