3
3
import os
4
4
import subprocess
5
5
import tempfile
6
+ from typing import Optional
6
7
from typing import Sequence
7
8
from xml .etree import ElementTree
8
9
@@ -20,11 +21,11 @@ class Catch2Facade(AbstractFacade):
20
21
"""
21
22
22
23
@classmethod
23
- def is_test_suite (
24
+ def get_catch_version (
24
25
cls ,
25
26
executable : str ,
26
27
harness_collect : Sequence [str ] = (),
27
- ) -> bool :
28
+ ) -> Optional [ str ] :
28
29
args = make_cmdline (harness_collect , executable , ["--help" ])
29
30
try :
30
31
output = subprocess .check_output (
@@ -33,25 +34,44 @@ def is_test_suite(
33
34
universal_newlines = True ,
34
35
)
35
36
except (subprocess .CalledProcessError , OSError ):
36
- return False
37
+ return None
37
38
else :
38
- return "--list-test-names-only" in output
39
+ return (
40
+ "v2"
41
+ if "--list-test-names-only" in output
42
+ else "v3"
43
+ if "--list-tests" in output
44
+ else None
45
+ )
46
+
47
+ @classmethod
48
+ def is_test_suite (
49
+ cls ,
50
+ executable : str ,
51
+ harness_collect : Sequence [str ] = (),
52
+ ) -> bool :
53
+ return cls .get_catch_version (executable , harness_collect ) in ["v2" , "v3" ]
39
54
40
55
def list_tests (
41
56
self ,
42
57
executable : str ,
43
58
harness_collect : Sequence [str ] = (),
44
59
) -> list [str ]:
45
60
"""
46
- Executes test with "--list-test-names-only" and gets list of tests
61
+ Executes test with "--list-test-names-only" (v2) or "--list-tests --verbosity quiet" (v3) and gets list of tests
47
62
parsing output like this:
48
63
49
64
1: All test cases reside in other .cpp files (empty)
50
65
2: Factorial of 0 is 1 (fail)
51
66
2: Factorials of 1 and higher are computed (pass)
52
67
"""
53
68
# This will return an exit code with the number of tests available
54
- args = make_cmdline (harness_collect , executable , ["--list-test-names-only" ])
69
+ exec_args = (
70
+ ["--list-test-names-only" ]
71
+ if self .get_catch_version (executable , harness_collect ) == "v2"
72
+ else ["--list-tests" , "--verbosity quiet" ]
73
+ )
74
+ args = make_cmdline (harness_collect , executable , exec_args )
55
75
try :
56
76
output = subprocess .check_output (
57
77
args ,
@@ -77,6 +97,11 @@ def run_test(
77
97
On Windows, ValueError is raised when path and start are on different drives.
78
98
In this case failing back to the absolute path.
79
99
"""
100
+ catch_version = self .get_catch_version (executable , harness )
101
+
102
+ if catch_version is None :
103
+ raise Exception ("Invalid Catch Version" )
104
+
80
105
try :
81
106
xml_filename = os .path .join (os .path .relpath (temp_dir ), "cpp-report.xml" )
82
107
except ValueError :
@@ -97,7 +122,9 @@ def run_test(
97
122
except subprocess .CalledProcessError as e :
98
123
output = e .output
99
124
100
- results = self ._parse_xml (xml_filename )
125
+ results = self ._parse_xml (
126
+ xml_filename , catch_version
127
+ )
101
128
102
129
for executed_test_id , failures , skipped in results :
103
130
if executed_test_id == test_id :
@@ -123,11 +150,16 @@ def run_test(
123
150
return [failure ], output
124
151
125
152
def _parse_xml (
126
- self , xml_filename : str
153
+ self , xml_filename : str , catch_version : str
127
154
) -> Sequence [tuple [str , Sequence [tuple [str , int , str ]], bool ]]:
128
155
root = ElementTree .parse (xml_filename )
129
156
result = []
130
- for test_suite in root .findall ("Group" ):
157
+ test_suites = (
158
+ root .findall ("Group" )
159
+ if catch_version == "v2"
160
+ else root .iter ("Catch2TestRun" )
161
+ )
162
+ for test_suite in test_suites :
131
163
for test_case in test_suite .findall ("TestCase" ):
132
164
test_name = test_case .attrib ["name" ]
133
165
test_result = test_case .find ("OverallResult" )
0 commit comments