Skip to content

Commit 1d230fa

Browse files
committed
support catch v3
1 parent fe4745c commit 1d230fa

File tree

7 files changed

+24024
-32
lines changed

7 files changed

+24024
-32
lines changed

src/pytest_cpp/catch2.py

+41-9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import subprocess
55
import tempfile
6+
from typing import Optional
67
from typing import Sequence
78
from xml.etree import ElementTree
89

@@ -20,11 +21,11 @@ class Catch2Facade(AbstractFacade):
2021
"""
2122

2223
@classmethod
23-
def is_test_suite(
24+
def get_catch_version(
2425
cls,
2526
executable: str,
2627
harness_collect: Sequence[str] = (),
27-
) -> bool:
28+
) -> Optional[str]:
2829
args = make_cmdline(harness_collect, executable, ["--help"])
2930
try:
3031
output = subprocess.check_output(
@@ -33,25 +34,44 @@ def is_test_suite(
3334
universal_newlines=True,
3435
)
3536
except (subprocess.CalledProcessError, OSError):
36-
return False
37+
return None
3738
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"]
3954

4055
def list_tests(
4156
self,
4257
executable: str,
4358
harness_collect: Sequence[str] = (),
4459
) -> list[str]:
4560
"""
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
4762
parsing output like this:
4863
4964
1: All test cases reside in other .cpp files (empty)
5065
2: Factorial of 0 is 1 (fail)
5166
2: Factorials of 1 and higher are computed (pass)
5267
"""
5368
# 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)
5575
try:
5676
output = subprocess.check_output(
5777
args,
@@ -77,6 +97,11 @@ def run_test(
7797
On Windows, ValueError is raised when path and start are on different drives.
7898
In this case failing back to the absolute path.
7999
"""
100+
catch_version = self.get_catch_version(executable, harness)
101+
102+
if catch_version is None:
103+
raise Exception("Invalid Catch Version")
104+
80105
try:
81106
xml_filename = os.path.join(os.path.relpath(temp_dir), "cpp-report.xml")
82107
except ValueError:
@@ -97,7 +122,9 @@ def run_test(
97122
except subprocess.CalledProcessError as e:
98123
output = e.output
99124

100-
results = self._parse_xml(xml_filename)
125+
results = self._parse_xml(
126+
xml_filename, catch_version
127+
)
101128

102129
for executed_test_id, failures, skipped in results:
103130
if executed_test_id == test_id:
@@ -123,11 +150,16 @@ def run_test(
123150
return [failure], output
124151

125152
def _parse_xml(
126-
self, xml_filename: str
153+
self, xml_filename: str, catch_version: str
127154
) -> Sequence[tuple[str, Sequence[tuple[str, int, str]], bool]]:
128155
root = ElementTree.parse(xml_filename)
129156
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:
131163
for test_case in test_suite.findall("TestCase"):
132164
test_name = test_case.attrib["name"]
133165
test_result = test_case.find("OverallResult")

tests/.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
!.gitignore
55
!*.h
66
!*.cpp
7+
!*.hpp
78
!*.cc
89
!*.py
910
!*.xml
1011
!README*
1112
!SCons*
12-
!catch.hpp
13+
14+
!catch2_v2
15+
!catch2_v3

tests/SConstruct

+12-4
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ if 'CXX' in os.environ:
1919

2020
env = Environment(**kwargs)
2121
genv = env.Clone(LIBS=['gtest'] + LIBS)
22-
c2env = env.Clone(CPPPATH=['.'])
22+
c2env = env.Clone(CPPPATH=['.', 'catch2_v2'])
2323

24-
Export('env genv c2env')
24+
catch2_v3 = env.Library('catch2_v3', ['catch2_v3/catch.cpp'])
25+
26+
c3env = env.Clone(CPPPATH=['.', 'catch2_v3'], LIBS=[catch2_v3])
27+
28+
Export('env genv c2env c3env')
2529

2630
genv.Program('gtest.cpp')
2731
genv.Program('gtest_args.cpp')
@@ -39,8 +43,12 @@ boost_files = [
3943
for filename in boost_files:
4044
env.Program(filename)
4145

42-
c2env.Program('catch2_success.cpp')
43-
c2env.Program('catch2_failure.cpp')
46+
for env, label in [(c3env, "_v3"), (c2env, "")]:
47+
catch2_success = env.Object(f'catch2_success{label}', 'catch2_success.cpp')
48+
catch2_failure = env.Object(f'catch2_failure{label}', 'catch2_failure.cpp')
49+
50+
env.Program(catch2_success)
51+
env.Program(catch2_failure)
4452

4553
SConscript('acceptance/googletest-samples/SConscript')
4654
SConscript('acceptance/boosttest-samples/SConscript')
File renamed without changes.

0 commit comments

Comments
 (0)