-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpytest_runner.py
69 lines (63 loc) · 1.98 KB
/
pytest_runner.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
from io import BytesIO
import os
import shlex
import subprocess
from typing import List, Optional
class PytestRunner:
def __init__(
self,
run_options: str = "",
collect_options: str = "",
stdout: bool = False,
) -> None:
self.__run_options = shlex.split(run_options) if run_options else []
self.__collect_options = shlex.split(collect_options) if collect_options else []
self.__stdout = None if stdout else subprocess.DEVNULL
def run(self, test_names: List[str]) -> bool:
return run_pytest_with_test_names(
test_names=test_names, args=["pytest", "--quiet"], stdout=self.__stdout
)
def collect_tests(self) -> List[str]:
r, w = os.pipe()
os.set_inheritable(w, True)
try:
subprocess.check_call(
[
"pytest",
"--collect-only",
"--bisect-tests-ids-to-fd",
str(w),
*self.__run_options,
*self.__collect_options,
],
close_fds=False,
stdout=self.__stdout,
stderr=subprocess.DEVNULL,
)
os.close(w)
with os.fdopen(r, closefd=False) as f:
return [l.strip() for l in f.readlines()]
finally:
os.closerange(r, w)
def run_pytest_with_test_names(
test_names: List[str], args: List[str], stdout: Optional[int]
) -> bool:
print("Running", len(test_names), "tests.")
r, w = os.pipe()
os.set_inheritable(r, True)
try:
p = subprocess.Popen(
[
*args,
"--bisect-tests-ids-from-fd",
str(r),
],
close_fds=False,
stdout=stdout,
stderr=subprocess.DEVNULL,
)
os.write(w, "\n".join(test_names).encode())
os.close(w)
return p.wait() == 0
finally:
os.closerange(r, w)