Skip to content

Commit cecdd01

Browse files
unterwegerKunterwegBrianThomasRoss
authored
#358 Add tests for the cli (#554)
* #358 Add tests for the cli * #358 Add tests for the cli * #358 Add tests for the cli - Fixed naming style. Co-authored-by: Kristof <[email protected]> Co-authored-by: Brian Ross <[email protected]>
1 parent 1295b28 commit cecdd01

File tree

2 files changed

+179
-4
lines changed

2 files changed

+179
-4
lines changed

src/penn_chime/cli.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
from .model.parameters import Parameters
77
from .model.sir import Sir
88

9-
10-
def main():
11-
"""Main."""
12-
p = Parameters.create(os.environ, sys.argv[1:])
9+
def run(argv):
10+
p = Parameters.create(os.environ, argv[1:])
1311
m = Sir(p)
1412

1513
for df, name in (
@@ -18,3 +16,7 @@ def main():
1816
(m.census_df, "projected_census"),
1917
):
2018
df.to_csv(f"{p.current_date}_{name}.csv")
19+
20+
def main():
21+
"""Main."""
22+
run(sys.argv)

tests/penn_chime/test_cli.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import pytest
2+
3+
import penn_chime.cli
4+
5+
from datetime import date, timedelta
6+
7+
def test_main_with_doubling_time():
8+
""""
9+
Tests a run via CLI with the minimum amount of parameters. Exponential
10+
factor is defined by doubling-time.
11+
"""
12+
arguments = [
13+
"pytest",
14+
"--current-hospitalized", "1",
15+
"--doubling-time", "2.5",
16+
"--hospitalized-days", "5",
17+
"--hospitalized-rate", "0.01",
18+
"--icu-days", "10",
19+
"--icu-rate", "0.5",
20+
"--market-share", "0.1",
21+
"--infectious-days", "5",
22+
"--max-y-axis", "10000",
23+
"--n-days", "200",
24+
"--recovered", "10",
25+
"--relative-contact-rate", "0.1",
26+
"--population", "1000000",
27+
"--ventilated-days", "5",
28+
"--ventilated-rate", "0.025"
29+
]
30+
31+
penn_chime.cli.run(arguments)
32+
33+
def test_main_with_date_first_hospitalized():
34+
""""
35+
Tests a run via CLI with the minimum amount of parameters. Exponential
36+
factor is defined by date-first-hospitalized.
37+
"""
38+
arguments = [
39+
"pytest",
40+
"--current-hospitalized", "69",
41+
"--current-date", "2020-04-14",
42+
"--date-first-hospitalized", "2020-04-01",
43+
"--hospitalized-days", "5",
44+
"--hospitalized-rate", "0.025",
45+
"--icu-days", "9",
46+
"--icu-rate", "0.075",
47+
"--market-share", "0.1",
48+
"--infectious-days", "14",
49+
"--max-y-axis", "1000",
50+
"--n-days", "30",
51+
"--recovered", "0",
52+
"--relative-contact-rate", "0.1",
53+
"--population", "1000000",
54+
"--ventilated-days", "10",
55+
"--ventilated-rate", "0.005"
56+
]
57+
58+
penn_chime.cli.run(arguments)
59+
60+
def test_failure_on_missing_parameters():
61+
"""Negative test to verify that an error is given when neither defining
62+
doubling-time nor date-first-hospitalized."""
63+
arguments = [
64+
"pytest",
65+
"--current-hospitalized", "69",
66+
"--hospitalized-days", "5",
67+
"--hospitalized-rate", "0.025",
68+
"--icu-days", "9",
69+
"--icu-rate", "0.075",
70+
"--market-share", "0.1",
71+
"--infectious-days", "14",
72+
"--max-y-axis", "1000",
73+
"--n-days", "30",
74+
"--recovered", "0",
75+
"--relative-contact-rate", "0.1",
76+
"--population", "1000000",
77+
"--ventilated-days", "10",
78+
"--ventilated-rate", "0.005"
79+
]
80+
81+
with pytest.raises(AssertionError):
82+
penn_chime.cli.run(arguments)
83+
84+
def test_main_with_csv_verification():
85+
"""Integration test for CLI. Runs a five-day simulation and verifies the
86+
content of the resulting csv files."""
87+
current_date = date.today().strftime("%Y-%m-%d")
88+
n_days = 5
89+
arguments = [
90+
"pytest",
91+
"--current-hospitalized", "1",
92+
"--current-date", current_date,
93+
"--doubling-time", "2.5",
94+
"--hospitalized-days", "5",
95+
"--hospitalized-rate", "0.01",
96+
"--icu-days", "10",
97+
"--icu-rate", "0.5",
98+
"--market-share", "0.1",
99+
"--infectious-days", "5",
100+
"--max-y-axis", "10000",
101+
"--n-days", str(n_days),
102+
"--recovered", "10",
103+
"--relative-contact-rate", "0.1",
104+
"--population", "1000000",
105+
"--ventilated-days", "5",
106+
"--ventilated-rate", "0.025"
107+
]
108+
109+
penn_chime.cli.run(arguments)
110+
111+
#Verify content of projected_admits.csv
112+
projected_admits_content = [
113+
[None, None, None],
114+
[0.5195079107728944,25.97539553864472,1.298769776932236],
115+
[0.6851383215271454,34.25691607635727,1.7128458038178636],
116+
[0.8129161146846768,40.64580573423383,2.0322902867116914],
117+
[1.029120162473117,51.456008123655835,2.5728004061827923],
118+
[1.3021513067257287,65.10756533628646,3.255378266814322],
119+
[1.6465388184586223,82.32694092293116,4.116347046146558],
120+
[2.0802813033400414,104.01406516700195,5.200703258350099]
121+
]
122+
123+
__validate_file(projected_admits_content, ",day,date,admits_hospitalized,admits_icu,admits_ventilated\n", current_date + "_projected_admits.csv")
124+
125+
#Verify content of projected_admits.csv
126+
projected_census_content = [
127+
[0.0,0.0,0.0],
128+
[0.5195079107728944,25.97539553864472,1.298769776932236],
129+
[1.2046462323000398,60.23231161500199,3.0116155807500995],
130+
[2.0175623469847164,100.87811734923582,5.043905867461791],
131+
[3.0466825094578334,152.33412547289166,7.616706273644583],
132+
[4.3488338161835625,217.4416908091781,10.872084540458905],
133+
[5.47586472386929,299.76863173210927,13.689661809673227],
134+
[6.871007705682186,403.7826968991112,17.17751926420546]
135+
]
136+
137+
__validate_file(projected_census_content, ",day,date,census_hospitalized,census_icu,census_ventilated\n", current_date + "_projected_census.csv")
138+
139+
#Verify content of sim_sir_w_date.csv
140+
sim_sir_w_date_content = [
141+
[999000.0,1000.0,10.0],
142+
[998480.4920892271,1319.5079107728943,210.0],
143+
[997795.3537677001,1740.7446501454608,473.901582154579],
144+
[996982.4376530153,2205.5118348010456,822.0505121836709],
145+
[995953.3174905422,2793.529630313953,1263.15287914388],
146+
[994651.1661838164,3536.9750109768916,1821.8588052066705],
147+
[993004.6273653577,4476.118827240136,2529.2538074020486],
148+
[990924.346062018,5661.176365132148,3424.4775728500767]
149+
]
150+
151+
__validate_file(sim_sir_w_date_content, ",day,date,susceptible,infected,recovered\n", current_date + "_sim_sir_w_date.csv")
152+
153+
154+
def __validate_file(reference_file_content, reference_file_header, reference_file_name):
155+
with open(reference_file_name, "r") as f:
156+
lines = f.readlines()
157+
assert len(lines) == len(reference_file_content) + 1
158+
assert lines[0] == reference_file_header
159+
160+
for i, row in enumerate(lines[1:]):
161+
reference_row = reference_file_content[i]
162+
tokens = row.split(",")
163+
row_date = date.today() + timedelta(days=i-2)
164+
assert int(tokens[0]) == i, f"Failed for file {reference_file_name} row {i+1}."
165+
assert int(tokens[1]) == i-2, f"Failed for file {reference_file_name} row {i+1}."
166+
assert tokens[2] == row_date.strftime("%Y-%m-%d"), f"Failed for file {reference_file_name} row {i+1}."
167+
print(f"'{tokens[3]},{tokens[4]},{tokens[5]}'")
168+
assert not tokens[3].strip() or float(tokens[3]) == pytest.approx(reference_row[0], 1e-10, 1e-1), f"Failed for file {reference_file_name} row {i+1}."
169+
assert not tokens[4].strip() or float(tokens[4]) == pytest.approx(reference_row[1], 1e-10, 1e-2), f"Failed for file {reference_file_name} row {i+1}."
170+
assert not tokens[5].strip() or float(tokens[5]) == pytest.approx(reference_row[2], 1e-10, 1e-3), f"Failed for file {reference_file_name} row {i+1}."
171+
172+
173+

0 commit comments

Comments
 (0)