Run built-in app tests#
Goal#
Execute the integration tests that ship inside each PlayMolecule app, to confirm the app and its environment are working before you build real jobs around it.
Minimal example#
from playmolecule.apps import proteinprepare
print(proteinprepare.tests) # list available tests
proteinprepare.tests.simple.run() # run one
Each named test runs the app end-to-end in a temporary directory, waits for completion, and asserts that the manifest’s expected_outputs files appear.
Discover tests#
print(proteinprepare.tests)
Each entry has a description, arguments, and an expected_outputs list:
[simple] 'Prepare 3PTB structure from RCSB'
- Arguments:
pdbid = 3ptb
- Expected outputs:
output.pdb
pka_plot.png
details.csv
[reprotonation] 'Prepare 3PTB but reprotonate specific residues'
...
Tests come from the app manifest’s tests block.
Run locally#
proteinprepare.tests.simple.run()
The test runs in a tempfile.TemporaryDirectory and prints a 🎉 Test '<name>' succeeded in N seconds! 🎉 line on success. Any missing expected output raises RuntimeError.
Run on SLURM#
proteinprepare.tests.simple.run(
queue="slurm",
dir="/shared/scratch/tests/",
partition="normalCPU",
ncpu=1,
ngpu=0,
)
When queue="slurm", you must pass dir= pointing to a path visible from the worker nodes — the default temp directory under /tmp/ won’t be there.
All extra kwargs are forwarded to run(), which forwards SLURM-specific ones to the queue.
Pin a test to a specific version#
To detect manifest drift across upgrades, call the test on a pinned version:
proteinprepare.v1.proteinprepare.tests.simple.run()
Gotchas#
Tests don’t return anything — they raise on failure. Wrap in
try/exceptif you’re driving them from a larger script.Test names that don’t start with a letter, or contain characters other than
[A-Za-z0-9_], are renamed at load time (-becomes_, leading digit becomestest_<n>). Usedir(app.tests)to see the actual attribute names.Test failures will leave the temp directory deleted (it’s a context manager). If you need to debug, pass
dir="./debug-runs/"and inspect the leftover contents — but note that forqueue=None(local) the cleanup still runs.