# Using app versions and tests **You will learn:** how to pin to a specific app version and run the test suite that ships with every app. **Prerequisites:** - [First app run](01-first-app-run.md) completed. Every PlayMolecule app is versioned. The bare app name (`proteinprepare`) is always an alias for the latest installed version — convenient for exploring, brittle if you want reproducibility. This tutorial shows the pieces you need to lock down. ## Setup ```python from playmolecule.apps import proteinprepare ``` ## Step 1 — See available versions The submodule for each version lives at `playmolecule.apps..`: ```python import playmolecule.apps.proteinprepare as pp_module print([name for name in dir(pp_module) if name.startswith("v")]) ``` If two versions are installed you'll see something like `['v1', 'v2']`. The unqualified `proteinprepare(...)` symbol is aliased to whichever version sorts as latest. (See {py:func}`~playmolecule.describe_apps` for the discovery API.) ## Step 2 — Pin to a specific version To freeze your script against drift, reach into the version submodule and call its function explicitly: ```python ed = proteinprepare.v1.proteinprepare(outdir="out", pdbid="3ptb") ``` `proteinprepare.v1` is the version submodule; `proteinprepare.v1.proteinprepare` is the dynamic function (same signature as the unqualified `proteinprepare(...)`, just pinned). Different versions can have different parameters — pinning is the only safe way to reproduce a result across upgrades. ## Step 3 — Look at built-in tests Every app ships a set of integration tests defined in its manifest: ```python print(proteinprepare.tests) ``` You'll see entries like: ```text [simple] 'Prepare 3PTB structure from RCSB' - Arguments: pdbid = 3ptb - Expected outputs: output.pdb pka_plot.png details.csv ``` Each named test exposes a `run()` method. ## Step 4 — Execute a test ```python proteinprepare.tests.simple.run() ``` This runs the test in a temporary directory, waits for completion, and asserts that the expected output files exist. A `🎉 Test '' succeeded in N seconds! 🎉` line means PlayMolecule and the app are correctly wired together — useful as a smoke test after installation or after {py:func}`~playmolecule.update_apps`. To run a test on SLURM instead (handy for GPU-bound apps you can't run locally): ```python proteinprepare.tests.simple.run( queue="slurm", dir="/shared/scratch/tests/", # must be visible to every SLURM worker partition="normalCPU", ncpu=1, ngpu=0, ) ``` Pass `dir=` whenever you submit to SLURM. Without it, the test runs in `/tmp/`, which is node-local on most clusters — the worker won't be able to read what your login node wrote. ## Recap - Each app exposes versioned submodules (`app.v1`, `app.v2`); the bare name aliases the latest. - Pin versions in production scripts so an `update_apps()` upgrade can't silently change behaviour. - `app.tests..run()` exercises the app end-to-end. Use it as a smoke test after install or upgrade. ## Next - [Running on SLURM](03-running-on-slurm.md) - [Select an app version](../howto/select-an-app-version.md) - [Apps and manifests](../explanation/apps-and-manifests.md)