Skip to content

Commit

Permalink
Fix galaxy testing for xunit reports in newer nose versions.
Browse files Browse the repository at this point in the history
Fixes planemo for galaxyproject/galaxy#172.
  • Loading branch information
jmchilton committed Apr 27, 2015
1 parent e4f5ea3 commit 33294d2
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 20 deletions.
20 changes: 4 additions & 16 deletions planemo/commands/cmd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,32 +256,20 @@ def __summarize_tests_full(

def __summarize_test_case(structured_data, testcase_el, **kwds):
summary_style = kwds.get("summary")
name_raw = testcase_el.attrib["name"]
tool_and_num = name_raw.split("TestForTool_", 1)[-1]
if "test_tool_" in tool_and_num:
tool, num = tool_and_num.split(".test_tool_", 1)
try:
num = int(num)
except ValueError:
pass
# Tempted to but something human friendly in here like
# num + 1 - but then it doesn't match HTML report.
label = "%s[%s]" % (tool, num)
else:
label = tool_and_num
test_id = galaxy_test.test_id(testcase_el)
passed = len(list(testcase_el)) == 0
if not passed:
state = click.style("failed", bold=True, fg='red')
else:
state = click.style("passed", bold=True, fg='green')
click.echo(label + ": " + state)
click.echo(test_id.label + ": " + state)
if summary_style != "minimal":
__print_command_line(structured_data, name_raw)
__print_command_line(structured_data, test_id)


def __print_command_line(structured_data, test_id):
try:
test = [d for d in structured_data if d["id"] == test_id][0]["data"]
test = [d for d in structured_data if d["id"] == test_id.id][0]["data"]
except (KeyError, IndexError):
# Failed to find structured data for this test - likely targetting
# and older Galaxy version.
Expand Down
65 changes: 61 additions & 4 deletions planemo/galaxy_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
""" Utilities for reasoning about Galaxy test results.
"""
from __future__ import absolute_import

from collections import namedtuple
import json
import xml.etree.ElementTree as ET

Expand Down Expand Up @@ -37,7 +39,7 @@ def __init__(
self.structured_data_by_id = structured_data_by_id

if output_xml_path:
self.xunit_tree = ET.parse(output_xml_path)
self.xunit_tree = parse_xunit_report(output_xml_path)
self.__merge_xunit()
self.has_details = True
else:
Expand Down Expand Up @@ -70,8 +72,8 @@ def __merge_xunit(self):
self.num_problems = num_skips + num_errors + num_failures

for testcase_el in self.xunit_testcase_elements:
id = testcase_el.get("name")
test_data = self.structured_data_by_id.get(id)
test = test_id(testcase_el)
test_data = self.structured_data_by_id.get(test.id)
if not test_data:
continue
problem_el = None
Expand All @@ -93,5 +95,60 @@ def all_tests_passed(self):

@property
def xunit_testcase_elements(self):
for testcase_el in self._xunit_root.findall("testcase"):
for testcase_el in find_testcases(self._xunit_root):
yield testcase_el


def parse_xunit_report(xunit_report_path):
return ET.parse(xunit_report_path)


def find_testcases(xunit_root):
return xunit_root.findall("testcase")


def test_id(testcase_el):
name_raw = testcase_el.attrib["name"]
if "TestForTool_" in name_raw:
raw_id = name_raw
else:
class_name = testcase_el.attrib["classname"]
raw_id = "{}.{}".format(class_name, name_raw)

name = None
num = None
if "TestForTool_" in raw_id:
tool_and_num = raw_id.split("TestForTool_")[-1]
if ".test_tool_" in tool_and_num:
name, num_str = tool_and_num.split(".test_tool_", 1)
num = _parse_num(num_str)
# Tempted to but something human friendly in here like
# num + 1 - but then it doesn't match HTML report.
else:
name = tool_and_num
else:
name = raw_id

return TestId(name, num, raw_id)


def _parse_num(num_str):
try:
num = int(num_str)
except ValueError:
num = None
return num


TestId = namedtuple("TestId", ["name", "num", "id"])


@property
def _label(self):
if self.num is not None:
return "{}[{}]".format(self.name, self.num)
else:
return self.id


TestId.label = _label
1 change: 1 addition & 0 deletions tests/data/xunit_nose_0_11.xml
Original file line number Diff line number Diff line change
@@ -0,0 +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>
1 change: 1 addition & 0 deletions tests/data/xunit_nose_1_3.xml
Original file line number Diff line number Diff line change
@@ -0,0 +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>
29 changes: 29 additions & 0 deletions tests/test_galaxy_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
""" Tests for the galaxy_test module :) """

import os

from .test_utils import TEST_DATA_DIR

from planemo import galaxy_test

nose_1_3_report = os.path.join(TEST_DATA_DIR, "xunit_nose_1_3.xml")
nose_0_11_report = os.path.join(TEST_DATA_DIR, "xunit_nose_0_11.xml")


def get_test_id_new():
_get_test_id(nose_1_3_report)


def get_test_id_old():
_get_test_id(nose_0_11_report)


def _get_test_id(path):
xml_tree = galaxy_test.parse_xunit_report(path)
root = xml_tree.getroot()
first_testcase = galaxy_test.find_testcases(root)[0]
test_id = galaxy_test.test_id(first_testcase)
assert test_id.label == "cat[0]"
expected_id = "functional.test_toolbox.TestForTool_cat.test_tool_000000"
assert test_id.id == expected_id
assert test_id.num == 0

0 comments on commit 33294d2

Please sign in to comment.