add --shorten-output-lines option so users can change how much is shown
[pytest-output-to-files.git] / tests / test_output_to_files.py
1 import pytest
2 import sys
3 from pathlib import Path
4 from pytest_output_to_files import _DEFAULT_LINE_LIMIT
5
6
7 def test_help_message(testdir):
8 # type: (pytest.Testdir) -> None
9 result = testdir.runpytest(
10 '--help',
11 )
12 # fnmatch_lines does an assertion internally
13 result.stdout.fnmatch_lines([
14 'shortening output:',
15 '*--shorten-output-dir=DIR*',
16 '*shorten test outputs by storing them in files in DIR and*',
17 '*returning just the first/last few lines. disable by*',
18 '*using --shorten-output-dir=""*',
19 '*--shorten-output-lines=LINES*',
20 '*change the number of lines shown by the*',
21 '*--shorten-output-dir option*',
22 ])
23
24
25 def do_stdout_stderr_check(testdir, additional_args, stdout_lines,
26 stderr_lines, enabled, line_limit):
27 # type: (pytest.Testdir, list[str], int, int, bool, int) -> pytest.RunResult
28 testdir.makepyfile(test_print=f"""
29 import sys
30
31 def test_print():
32 for i in range({stdout_lines}):
33 print(f'in stdout {{i}}')
34 for i in range({stderr_lines}):
35 print(f'in stderr {{i}}', file=sys.stderr)
36 assert False
37 """)
38
39 full_stdout = ''.join(f'in stdout {i}\n' for i in range(stdout_lines))
40 full_stderr = ''.join(f'in stderr {i}\n' for i in range(stderr_lines))
41
42 result = testdir.runpytest('-v', *additional_args)
43
44 test_out_path = Path(testdir.tmpdir)
45 test_out_path /= "test-out"
46 test_print_path = test_out_path / "test_print_py"
47 test_print_path /= "test_print"
48 call_stdout_path = test_print_path / "call-stdout.txt"
49 call_stderr_path = test_print_path / "call-stderr.txt"
50
51 lines = ['*--- Captured stdout call ---*']
52 hr = '-' * 50
53 if enabled and stdout_lines >= line_limit:
54 trimmed_msg = ("Output Trimmed, Full output in: "
55 "test-out/test_print_py/test_print/call-stdout.txt")
56 lines.append(trimmed_msg)
57 lines.append(hr)
58 for i in range((line_limit + 1) // 2):
59 lines.append(f'in stdout {i}')
60 lines.append(hr)
61 lines.append(trimmed_msg)
62 lines.append(hr)
63 for i in range(stdout_lines - line_limit // 2, stdout_lines):
64 lines.append(f'in stdout {i}')
65 lines.append(hr)
66 lines.append(trimmed_msg)
67 else:
68 for i in range(stdout_lines):
69 lines.append(f'in stdout {i}')
70 lines.append('*--- Captured stderr call ---*')
71 if enabled and stderr_lines >= line_limit:
72 trimmed_msg = ("Output Trimmed, Full output in: "
73 "test-out/test_print_py/test_print/call-stderr.txt")
74 lines.append(trimmed_msg)
75 lines.append(hr)
76 for i in range((line_limit + 1) // 2):
77 lines.append(f'in stderr {i}')
78 lines.append(hr)
79 lines.append(trimmed_msg)
80 lines.append(hr)
81 for i in range(stderr_lines - line_limit // 2, stderr_lines):
82 lines.append(f'in stderr {i}')
83 lines.append(hr)
84 lines.append(trimmed_msg)
85 else:
86 for i in range(stderr_lines):
87 lines.append(f'in stderr {i}')
88 lines.append("*====*")
89
90 result.stdout.fnmatch_lines(lines, consecutive=True)
91
92 result.stdout.fnmatch_lines([
93 'FAILED test_print.py::test_print *',
94 ])
95
96 if enabled:
97 for empty_file in ("setup-stdout.txt", "setup-stderr.txt",
98 "teardown-stdout.txt", "teardown-stderr.txt"):
99 assert (test_print_path / empty_file).read_text("utf-8") == ""
100 assert call_stdout_path.read_text("utf-8") == full_stdout
101 assert call_stderr_path.read_text("utf-8") == full_stderr
102 call_stdout_path.unlink() # remove big files
103 call_stderr_path.unlink() # remove big files
104 else:
105 assert not test_out_path.exists()
106 assert result.ret != 0
107
108 return result
109
110
111 def test_ini_setting(testdir):
112 # type: (pytest.Testdir) -> None
113 testdir.makeini("""
114 [pytest]
115 shorten-output-dir = test-out
116 """)
117
118 do_stdout_stderr_check(testdir, [], 1, 1, True,
119 line_limit=_DEFAULT_LINE_LIMIT)
120
121
122 def test_nothing(testdir):
123 # type: (pytest.Testdir) -> None
124 do_stdout_stderr_check(testdir, [], 1, 1, False,
125 line_limit=_DEFAULT_LINE_LIMIT)
126
127
128 def test_arg(testdir):
129 # type: (pytest.Testdir) -> None
130 do_stdout_stderr_check(
131 testdir, ["--shorten-output-dir=test-out"], 1, 1, True,
132 line_limit=_DEFAULT_LINE_LIMIT)
133
134
135 def test_arg_override_ini(testdir):
136 # type: (pytest.Testdir) -> None
137 testdir.makeini("""
138 [pytest]
139 shorten-output-dir = test-out
140 """)
141
142 do_stdout_stderr_check(
143 testdir, ["--shorten-output-dir="], 1, 1, False,
144 line_limit=_DEFAULT_LINE_LIMIT)
145
146
147 def test_disable_capture(testdir):
148 # type: (pytest.Testdir) -> None
149 testdir.makeini("""
150 [pytest]
151 shorten-output-dir = test-out
152 """)
153
154 testdir.makepyfile(test_print=f"""
155 import sys
156
157 def test_print():
158 print(f'in stdout')
159 print(f'in stderr', file=sys.stderr)
160 assert False
161 """)
162
163 result = testdir.runpytest('-v', '-s')
164
165 test_out_path = Path(testdir.tmpdir)
166 test_out_path /= "test-out"
167
168 assert not test_out_path.exists()
169
170 result.stdout.fnmatch_lines(['test_print.py::test_print*in stdout'])
171 result.stderr.fnmatch_lines(['in stderr'])
172
173 assert result.ret != 0
174
175
176 def test_20k_disabled(testdir):
177 # type: (pytest.Testdir) -> None
178 do_stdout_stderr_check(testdir, [], 20000, 20000, False,
179 line_limit=_DEFAULT_LINE_LIMIT)
180
181
182 def test_20k(testdir):
183 # type: (pytest.Testdir) -> None
184 do_stdout_stderr_check(
185 testdir, ["--shorten-output-dir=test-out"], 20000, 20000, True,
186 line_limit=_DEFAULT_LINE_LIMIT)
187
188
189 def test_21k(testdir):
190 # type: (pytest.Testdir) -> None
191 do_stdout_stderr_check(
192 testdir, ["--shorten-output-dir=test-out"], 21000, 21000, True,
193 line_limit=_DEFAULT_LINE_LIMIT)
194
195
196 def test_22k(testdir):
197 # type: (pytest.Testdir) -> None
198 do_stdout_stderr_check(
199 testdir, ["--shorten-output-dir=test-out"], 22000, 22000, True,
200 line_limit=_DEFAULT_LINE_LIMIT)
201
202
203 def test_half(testdir):
204 # type: (pytest.Testdir) -> None
205 lines = _DEFAULT_LINE_LIMIT // 2
206 do_stdout_stderr_check(
207 testdir, ["--shorten-output-dir=test-out"], lines, lines, True,
208 line_limit=_DEFAULT_LINE_LIMIT)
209
210
211 def test_75_percent(testdir):
212 # type: (pytest.Testdir) -> None
213 lines = _DEFAULT_LINE_LIMIT * 3 // 4
214 do_stdout_stderr_check(
215 testdir, ["--shorten-output-dir=test-out"], lines, lines, True,
216 line_limit=_DEFAULT_LINE_LIMIT)
217
218
219 def test_limit_minus_two(testdir):
220 # type: (pytest.Testdir) -> None
221 lines = _DEFAULT_LINE_LIMIT - 2
222 do_stdout_stderr_check(
223 testdir, ["--shorten-output-dir=test-out"], lines, lines, True,
224 line_limit=_DEFAULT_LINE_LIMIT)
225
226
227 def test_limit_minus_one(testdir):
228 # type: (pytest.Testdir) -> None
229 lines = _DEFAULT_LINE_LIMIT - 1
230 do_stdout_stderr_check(
231 testdir, ["--shorten-output-dir=test-out"], lines, lines, True,
232 line_limit=_DEFAULT_LINE_LIMIT)
233
234
235 def test_limit(testdir):
236 # type: (pytest.Testdir) -> None
237 lines = _DEFAULT_LINE_LIMIT
238 do_stdout_stderr_check(
239 testdir, ["--shorten-output-dir=test-out"], lines, lines, True,
240 line_limit=_DEFAULT_LINE_LIMIT)
241
242
243 def test_limit_plus_one(testdir):
244 # type: (pytest.Testdir) -> None
245 lines = _DEFAULT_LINE_LIMIT + 1
246 do_stdout_stderr_check(
247 testdir, ["--shorten-output-dir=test-out"], lines, lines, True,
248 line_limit=_DEFAULT_LINE_LIMIT)
249
250
251 def test_limit_plus_two(testdir):
252 # type: (pytest.Testdir) -> None
253 lines = _DEFAULT_LINE_LIMIT + 2
254 do_stdout_stderr_check(
255 testdir, ["--shorten-output-dir=test-out"], lines, lines, True,
256 line_limit=_DEFAULT_LINE_LIMIT)
257
258
259 def test_1M(testdir):
260 # type: (pytest.Testdir) -> None
261 lines = 1_000_000
262 do_stdout_stderr_check(
263 testdir, ["--shorten-output-dir=test-out"], lines, lines, True,
264 line_limit=_DEFAULT_LINE_LIMIT)
265
266
267 def test_small_limit_minus_one(testdir):
268 # type: (pytest.Testdir) -> None
269 line_limit = 50
270 lines = line_limit - 1
271 do_stdout_stderr_check(testdir,
272 ["--shorten-output-dir=test-out",
273 f"--shorten-output-lines={line_limit}"],
274 lines, lines, True, line_limit=line_limit)
275
276
277 def test_small_limit(testdir):
278 # type: (pytest.Testdir) -> None
279 line_limit = 50
280 lines = line_limit
281 do_stdout_stderr_check(testdir,
282 ["--shorten-output-dir=test-out",
283 f"--shorten-output-lines={line_limit}"],
284 lines, lines, True, line_limit=line_limit)
285
286
287 def test_small_limit_plus_one(testdir):
288 # type: (pytest.Testdir) -> None
289 line_limit = 50
290 lines = line_limit + 1
291 do_stdout_stderr_check(testdir,
292 ["--shorten-output-dir=test-out",
293 f"--shorten-output-lines={line_limit}"],
294 lines, lines, True, line_limit=line_limit)
295
296
297 def test_large_limit_minus_one(testdir):
298 # type: (pytest.Testdir) -> None
299 line_limit = 200
300 lines = line_limit - 1
301 do_stdout_stderr_check(testdir,
302 ["--shorten-output-dir=test-out",
303 f"--shorten-output-lines={line_limit}"],
304 lines, lines, True, line_limit=line_limit)
305
306
307 def test_large_limit(testdir):
308 # type: (pytest.Testdir) -> None
309 line_limit = 200
310 lines = line_limit
311 do_stdout_stderr_check(testdir,
312 ["--shorten-output-dir=test-out",
313 f"--shorten-output-lines={line_limit}"],
314 lines, lines, True, line_limit=line_limit)
315
316
317 def test_large_limit_plus_one(testdir):
318 # type: (pytest.Testdir) -> None
319 line_limit = 200
320 lines = line_limit + 1
321 do_stdout_stderr_check(testdir,
322 ["--shorten-output-dir=test-out",
323 f"--shorten-output-lines={line_limit}"],
324 lines, lines, True, line_limit=line_limit)
325
326
327 if __name__ == "__main__":
328 sys.exit(pytest.main())