Skip to content

Commit 33294d2

Browse files
committed
Fix galaxy testing for xunit reports in newer nose versions.
Fixes planemo for galaxyproject/galaxy#172.
1 parent e4f5ea3 commit 33294d2

File tree

5 files changed

+96
-20
lines changed

5 files changed

+96
-20
lines changed

planemo/commands/cmd_test.py

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -256,32 +256,20 @@ def __summarize_tests_full(
256256

257257
def __summarize_test_case(structured_data, testcase_el, **kwds):
258258
summary_style = kwds.get("summary")
259-
name_raw = testcase_el.attrib["name"]
260-
tool_and_num = name_raw.split("TestForTool_", 1)[-1]
261-
if "test_tool_" in tool_and_num:
262-
tool, num = tool_and_num.split(".test_tool_", 1)
263-
try:
264-
num = int(num)
265-
except ValueError:
266-
pass
267-
# Tempted to but something human friendly in here like
268-
# num + 1 - but then it doesn't match HTML report.
269-
label = "%s[%s]" % (tool, num)
270-
else:
271-
label = tool_and_num
259+
test_id = galaxy_test.test_id(testcase_el)
272260
passed = len(list(testcase_el)) == 0
273261
if not passed:
274262
state = click.style("failed", bold=True, fg='red')
275263
else:
276264
state = click.style("passed", bold=True, fg='green')
277-
click.echo(label + ": " + state)
265+
click.echo(test_id.label + ": " + state)
278266
if summary_style != "minimal":
279-
__print_command_line(structured_data, name_raw)
267+
__print_command_line(structured_data, test_id)
280268

281269

282270
def __print_command_line(structured_data, test_id):
283271
try:
284-
test = [d for d in structured_data if d["id"] == test_id][0]["data"]
272+
test = [d for d in structured_data if d["id"] == test_id.id][0]["data"]
285273
except (KeyError, IndexError):
286274
# Failed to find structured data for this test - likely targetting
287275
# and older Galaxy version.

planemo/galaxy_test.py

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
""" Utilities for reasoning about Galaxy test results.
22
"""
33
from __future__ import absolute_import
4+
5+
from collections import namedtuple
46
import json
57
import xml.etree.ElementTree as ET
68

@@ -37,7 +39,7 @@ def __init__(
3739
self.structured_data_by_id = structured_data_by_id
3840

3941
if output_xml_path:
40-
self.xunit_tree = ET.parse(output_xml_path)
42+
self.xunit_tree = parse_xunit_report(output_xml_path)
4143
self.__merge_xunit()
4244
self.has_details = True
4345
else:
@@ -70,8 +72,8 @@ def __merge_xunit(self):
7072
self.num_problems = num_skips + num_errors + num_failures
7173

7274
for testcase_el in self.xunit_testcase_elements:
73-
id = testcase_el.get("name")
74-
test_data = self.structured_data_by_id.get(id)
75+
test = test_id(testcase_el)
76+
test_data = self.structured_data_by_id.get(test.id)
7577
if not test_data:
7678
continue
7779
problem_el = None
@@ -93,5 +95,60 @@ def all_tests_passed(self):
9395

9496
@property
9597
def xunit_testcase_elements(self):
96-
for testcase_el in self._xunit_root.findall("testcase"):
98+
for testcase_el in find_testcases(self._xunit_root):
9799
yield testcase_el
100+
101+
102+
def parse_xunit_report(xunit_report_path):
103+
return ET.parse(xunit_report_path)
104+
105+
106+
def find_testcases(xunit_root):
107+
return xunit_root.findall("testcase")
108+
109+
110+
def test_id(testcase_el):
111+
name_raw = testcase_el.attrib["name"]
112+
if "TestForTool_" in name_raw:
113+
raw_id = name_raw
114+
else:
115+
class_name = testcase_el.attrib["classname"]
116+
raw_id = "{}.{}".format(class_name, name_raw)
117+
118+
name = None
119+
num = None
120+
if "TestForTool_" in raw_id:
121+
tool_and_num = raw_id.split("TestForTool_")[-1]
122+
if ".test_tool_" in tool_and_num:
123+
name, num_str = tool_and_num.split(".test_tool_", 1)
124+
num = _parse_num(num_str)
125+
# Tempted to but something human friendly in here like
126+
# num + 1 - but then it doesn't match HTML report.
127+
else:
128+
name = tool_and_num
129+
else:
130+
name = raw_id
131+
132+
return TestId(name, num, raw_id)
133+
134+
135+
def _parse_num(num_str):
136+
try:
137+
num = int(num_str)
138+
except ValueError:
139+
num = None
140+
return num
141+
142+
143+
TestId = namedtuple("TestId", ["name", "num", "id"])
144+
145+
146+
@property
147+
def _label(self):
148+
if self.num is not None:
149+
return "{}[{}]".format(self.name, self.num)
150+
else:
151+
return self.id
152+
153+
154+
TestId.label = _label

tests/data/xunit_nose_0_11.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version="1.0" encoding="UTF-8"?><testsuite name="nosetests" tests="1" errors="0" failures="0" skip="0"><testcase classname="functional.test_toolbox.TestForTool_cat" name="functional.test_toolbox.TestForTool_cat.test_tool_000000" time="13" /></testsuite>

tests/data/xunit_nose_1_3.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?xml version="1.0" encoding="UTF-8"?><testsuite name="nosetests" tests="3" errors="0" failures="0" skip="0"><testcase classname="functional.test_toolbox.TestForTool_cat" name="test_tool_000000" time="12.190"></testcase></testsuite>

tests/test_galaxy_test.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
""" Tests for the galaxy_test module :) """
2+
3+
import os
4+
5+
from .test_utils import TEST_DATA_DIR
6+
7+
from planemo import galaxy_test
8+
9+
nose_1_3_report = os.path.join(TEST_DATA_DIR, "xunit_nose_1_3.xml")
10+
nose_0_11_report = os.path.join(TEST_DATA_DIR, "xunit_nose_0_11.xml")
11+
12+
13+
def get_test_id_new():
14+
_get_test_id(nose_1_3_report)
15+
16+
17+
def get_test_id_old():
18+
_get_test_id(nose_0_11_report)
19+
20+
21+
def _get_test_id(path):
22+
xml_tree = galaxy_test.parse_xunit_report(path)
23+
root = xml_tree.getroot()
24+
first_testcase = galaxy_test.find_testcases(root)[0]
25+
test_id = galaxy_test.test_id(first_testcase)
26+
assert test_id.label == "cat[0]"
27+
expected_id = "functional.test_toolbox.TestForTool_cat.test_tool_000000"
28+
assert test_id.id == expected_id
29+
assert test_id.num == 0

0 commit comments

Comments
 (0)