-
Notifications
You must be signed in to change notification settings - Fork 2
/
test_plotly_programs.py
162 lines (120 loc) · 5.13 KB
/
test_plotly_programs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
"""Test all Plotly programs.
Chapter 15: Rolling dice
Chapter 16: Earthquake plots
Chapter 17: Python repos?
Overall approach:
- Copy code to a tmp dir.
- Modify code to save html file instead of opening tmp file in browser.
- Compare output files against reference files.
Notes:
- Need to call write_html() and generate full file, because that's what users see.
- Also, that lets me open the html file and visually inspect what's generated.
- But, the full file includes hashes and version numbers.
- Some of those can be replaced with dummy values, some are harder or not necessary.
- Also, can call write_html(include_plotly_js=False). Can't open and view file, but it's
the code that represents the plot. Call this in addition to full plot, and run assertion
against this.
- Can also call write_image(), and just do an image comparison.
Should probably call this in addition to write_html(), not replacing it.
- Should definitely write over fig.show().
- If testing against write_html() even without js becomes too fragile as versions change,
base all plotly testing on write_image(). If that's flaky, consider stripping metadata
for file comparisons.
"""
from pathlib import Path
import os, shutil, filecmp, re
import pytest
import utils
die_programs = [
"chapter_15/rolling_dice/die_visual.py",
"chapter_15/rolling_dice/dice_visual.py",
"chapter_15/rolling_dice/dice_visual_d6d10.py",
]
@pytest.mark.parametrize("test_file", die_programs)
def test_die_program(tmp_path, python_cmd, test_file):
# Copy program file to temp dir.
path = Path(__file__).parents[1] / test_file
dest_path = tmp_path / path.name
shutil.copy(path, dest_path)
# Copy die.py to temp dir.
path_die = path.parent / "die.py"
dest_path_die = tmp_path / "die.py"
shutil.copy(path_die, dest_path_die)
# Modify the program file for testing.
# Read all lines except fig.show().
lines = dest_path.read_text().splitlines()[:-1]
# Set random seed.
lines.insert(0, "import random")
lines.insert(5, "random.seed(23)")
# Add the call to fig.write_html().
output_filename = path.name.replace(".py", ".html")
save_cmd = f'fig.write_html("{output_filename}")'
lines.append(save_cmd)
contents = "\n".join(lines)
dest_path.write_text(contents)
# Run the program.
os.chdir(tmp_path)
cmd = f"{python_cmd} {path.name}"
output = utils.run_command(cmd)
# Verify the output file exists.
output_path = tmp_path / output_filename
assert output_path.exists()
utils.replace_plotly_hash(output_path)
# Print output file path, so it's easy to find.
print("\n***** Plotly output:", output_path)
reference_file_path = (Path(__file__).parent /
"reference_files" / output_filename)
assert filecmp.cmp(output_path, reference_file_path)
def test_eq_explore_data(tmp_path, python_cmd):
# Copy .py and data files to tmp dir.
path_py = (Path(__file__).parents[1] / "chapter_16"
/ "mapping_global_datasets" / "eq_explore_data.py")
path_data = (path_py.parent / "eq_data"
/ "eq_data_1_day_m1.geojson")
dest_data_dir = tmp_path / "eq_data"
dest_data_dir.mkdir()
dest_path_py = tmp_path / path_py.name
dest_path_data = dest_data_dir / path_data.name
shutil.copy(path_py, dest_path_py)
shutil.copy(path_data, dest_path_data)
# Run file.
os.chdir(tmp_path)
cmd = f"{python_cmd} {path_py.name}"
output = utils.run_command(cmd)
assert output == "[1.6, 1.6, 2.2, 3.7, 2.92000008, 1.4, 4.6, 4.5, 1.9, 1.8]\n[-150.7585, -153.4716, -148.7531, -159.6267, -155.248336791992]\n[61.7591, 59.3152, 63.1633, 54.5612, 18.7551670074463]"
def test_eq_world_map(tmp_path, python_cmd):
# Copy .py and data files to tmp dir.
path_py = (Path(__file__).parents[1] / "chapter_16"
/ "mapping_global_datasets" / "eq_world_map.py")
path_data = (path_py.parent / "eq_data"
/ "eq_data_30_day_m1.geojson")
dest_data_dir = tmp_path / "eq_data"
dest_data_dir.mkdir()
dest_path_py = tmp_path / path_py.name
dest_path_data = dest_data_dir / path_data.name
shutil.copy(path_py, dest_path_py)
shutil.copy(path_data, dest_path_data)
# Modify the program file for testing.
lines = dest_path_py.read_text().splitlines()[:-1]
# Set random seed.
lines.insert(0, "import random")
lines.insert(6, "random.seed(23)")
# Add the call to fig.write_html().
output_filename = path_py.name.replace(".py", ".html")
save_cmd = f'fig.write_html("{output_filename}")'
lines.append(save_cmd)
contents = "\n".join(lines)
dest_path_py.write_text(contents)
# Run file.
os.chdir(tmp_path)
cmd = f"{python_cmd} {path_py.name}"
output = utils.run_command(cmd)
# Verify the output file exists.
output_path = tmp_path / output_filename
assert output_path.exists()
utils.replace_plotly_hash(output_path)
# Print output file path, so it's easy to find.
print("\n***** Plotly output:", output_path)
reference_file_path = (Path(__file__).parent /
"reference_files" / output_filename)
assert filecmp.cmp(output_path, reference_file_path)