Skip to content

Commit 1cf2ac6

Browse files
committed
Add test infrastructure for model results
Fixes #5 Fixes timtroendle#28 Fixes timtroendle#31
1 parent 08011d9 commit 1cf2ac6

File tree

4 files changed

+62
-12
lines changed

4 files changed

+62
-12
lines changed

default/{{cookiecutter.project_short_name}}/Snakefile

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ rule all:
2323
message: "Run entire analysis and compile report."
2424
input:
2525
"build/report.html",
26-
"build/test-report.html"
26+
"build/test.success"
2727

2828

2929
rule run:
@@ -102,7 +102,16 @@ rule clean: # removes all generated results
102102

103103

104104
rule test:
105-
conda: "envs/test.yaml"
106-
output: "build/test-report.html"
107-
shell:
108-
"py.test --html={output} --self-contained-html"
105+
# To add more tests, do
106+
# (1) Add to-be-tested workflow outputs as inputs to this rule.
107+
# (2) Turn them into pytest fixtures in tests/test_runner.py.
108+
# (3) Create or reuse a test file in tests/my-test.py and use fixtures in tests.
109+
message: "Run tests"
110+
input:
111+
test_dir = "tests",
112+
tests = map(str, Path("tests").glob("**/test_*.py")),
113+
model_results = rules.run.output[0],
114+
log: "build/test-report.html"
115+
output: "build/test.success"
116+
conda: "./envs/test.yaml"
117+
script: "./tests/test_runner.py"

default/{{cookiecutter.project_short_name}}/envs/test.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,3 @@ dependencies:
77
- pandas=2.0.1
88
- pytest=7.3.1
99
- pytest-html=4.1.1
10-
- pip=23.1.2
11-
- pip:
12-
- pytest-pythonpath # adds the root path "./" to PYTHONPATH
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
"""Test case for the model."""
2-
import scripts.model
1+
"""Test case for the model results.
32
3+
Pytest fixtures are provided from within the test runner.
4+
"""
45

5-
def test_model():
6-
assert scripts.model.linear_model(slope=1, x0=4, x=0) == 4
6+
7+
def test_model_results_at_0(model_results):
8+
assert model_results[0] == 5
9+
10+
11+
def test_model_results_at_1(model_results):
12+
assert model_results[1] == 9
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import sys
2+
from pathlib import Path
3+
4+
import pandas as pd
5+
import pytest
6+
7+
8+
def run_test(snakemake):
9+
exit_code = pytest.main(
10+
[
11+
snakemake.input.test_dir,
12+
f"--html={snakemake.log[0]}",
13+
"--self-contained-html",
14+
"--verbose"
15+
],
16+
plugins=[
17+
_create_config_plugin(snakemake=snakemake)
18+
]
19+
)
20+
if exit_code == 0:
21+
Path(snakemake.output[0]).touch()
22+
sys.exit(exit_code)
23+
24+
25+
def _create_config_plugin(snakemake):
26+
"""Creates fixtures from Snakemake configuration."""
27+
28+
class SnakemakeConfigPlugin():
29+
30+
@pytest.fixture()
31+
def model_results(self):
32+
return pd.read_pickle(snakemake.input.model_results)
33+
34+
return SnakemakeConfigPlugin()
35+
36+
37+
if __name__ == "__main__":
38+
run_test(snakemake)

0 commit comments

Comments
 (0)