|
1 | 1 | # Testing |
2 | 2 |
|
3 | | -After reading through the [basic execution](basic_execution.md) and |
4 | | -[configuration](configuration.md) instructions it may be helpful to run a few |
5 | | -tests. |
| 3 | +ShapePipe has two complementary ways to check that things work: the automated |
| 4 | +**test suite** (run by CI, and by you during development) and a **smoke run** of |
| 5 | +the bundled example pipeline. |
6 | 6 |
|
7 | | -ShapePipe includes some dummy modules for testing purposes |
| 7 | +## The automated test suite |
8 | 8 |
|
9 | | -- `python_example_runner` : an example of a module written entirely in Python |
10 | | -- `serial_example_runner` : an example of a module that is run in serial mode |
11 | | -- `execute_example_runner` : an example of a module that calls a system |
12 | | - executable |
| 9 | +The test suite runs with [pytest](https://docs.pytest.org/) and lives in two |
| 10 | +trees: |
13 | 11 |
|
14 | | -None of these modules do anything particularly interesting, but they can be run |
15 | | -to test that ShapePipe is up and running. |
| 12 | +- `tests/unit/` — **structural** tests, one parametrized case per file: every |
| 13 | + shell script parses (`bash -n`), every example config parses, every |
| 14 | + `shapepipe.*` submodule imports, every `[project.scripts]` entry handles |
| 15 | + `-h`, and every `*_runner.py` carries its `@module_runner` metadata. Cheap, |
| 16 | + broad, and good at catching the dumb-but-real regressions (a syntax error, a |
| 17 | + broken import, a renamed entry point). |
| 18 | +- `src/shapepipe/tests/` — **unit, property-based, and integration** tests for |
| 19 | + the analytic surface: pure helpers and geometry (coordinate round-trips, |
| 20 | + postage-stamp shapes, the MegaCam CCD flip), tested both by example and with |
| 21 | + [Hypothesis](https://hypothesis.readthedocs.io/) property tests where a |
| 22 | + function has a clear invariant. Integration tests that need the astromatic |
| 23 | + binaries (Source Extractor, PSFEx) build synthetic FITS on the fly rather |
| 24 | + than requiring survey data. |
16 | 25 |
|
17 | | -The [example](https://github.com/CosmoStat/shapepipe/tree/develop/example) |
18 | | -directory contains an example config file called `config.ini` that runs all of |
19 | | -these dummy modules. ShapePipe can be run with this config file as follows |
| 26 | +**CI is the single gate.** On every pull request and every push to `develop`, |
| 27 | +`.github/workflows/deploy-image.yml` builds the dev image and runs the suite |
| 28 | +*inside it* — so the tests exercise exactly the environment that ships. A green |
| 29 | +check means the container actually works. |
| 30 | + |
| 31 | +### Running it yourself |
| 32 | + |
| 33 | +The supported way is inside the dev image (it carries the `test` extra and the |
| 34 | +astromatic binaries), exactly as CI does: |
| 35 | + |
| 36 | +```bash |
| 37 | +docker run --rm -e HYPOTHESIS_PROFILE=ci \ |
| 38 | + ghcr.io/cosmostat/shapepipe:develop pytest -rX |
| 39 | +``` |
| 40 | + |
| 41 | +From a development checkout (e.g. inside an Apptainer sandbox with the repo |
| 42 | +bind-mounted), run pytest directly: |
| 43 | + |
| 44 | +```bash |
| 45 | +pytest # the whole suite, with coverage reported |
| 46 | +pytest tests/unit # just the fast structural tier |
| 47 | +``` |
| 48 | + |
| 49 | +The `ci` Hypothesis profile is deterministic (fixed seed, capped examples) so CI |
| 50 | +is fast and reproducible; running without it locally explores more widely. |
| 51 | +Coverage is reported (`--cov-report=term-missing`) but not gated. |
| 52 | + |
| 53 | +## Smoke test — the example pipeline |
| 54 | + |
| 55 | +To confirm a fresh install runs end to end, the |
| 56 | +[example](https://github.com/CosmoStat/shapepipe/tree/develop/example) directory |
| 57 | +contains a `config.ini` that chains a few dummy modules: |
| 58 | + |
| 59 | +- `python_example_runner` — a module written entirely in Python |
| 60 | +- `serial_example_runner` — a module run in serial mode |
| 61 | +- `execute_example_runner` — a module that calls a system executable |
| 62 | + |
| 63 | +None do anything scientifically interesting, but running them confirms ShapePipe |
| 64 | +is up: |
20 | 65 |
|
21 | 66 | ```bash |
22 | 67 | shapepipe_run -c ./example/config.ini |
23 | 68 | ``` |
24 | 69 |
|
25 | | -The output of this run will be saved to `./example/output`. If you want a |
26 | | -more concrete understanding of what each of the configuration options does you |
27 | | -can modify `config.ini` and see what happens. |
| 70 | +Output is saved to `./example/output`. Inside the container, the |
| 71 | +`shapepipe_run_example` wrapper does the same against a writable copy of the |
| 72 | +example tree, so it works even on a read-only (apptainer/SIF) filesystem. |
0 commit comments