From 5b855027d0be7193592c35bffabaa2b6b49e8142 Mon Sep 17 00:00:00 2001 From: Stanislav Zubov Date: Tue, 10 Apr 2018 12:22:39 +0700 Subject: [PATCH] xunit/add-block-for-each-test-failed-at-setupclass (#34) --- CHANGELOG.md | 14 +++++++++----- lode_runner/lode_merge_xunit.py | 12 ++++++++++-- lode_runner/plugins/xunit.py | 19 +++++++++++++++++++ setup.py | 2 +- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cefa40a..8c8e9a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,20 +1,24 @@ +## 0.4.6 + +- XUnit plugin now also drops separate block to XUnit report for all single tests (even if failed on setUpClass) + ## 0.4.5 -- NoseId plugin also collects tests failed during setup test suite +- NoseId plugin also collects all tests of failed on setup TestSuites ## 0.4.4 -- Add 'lode_runner.plugins.Suppressor' plugin. Allows suppress any exceptions in tearDown-methods +- Add `lode_runner.plugins.Suppressor` plugin. Allows suppress any exceptions in tearDown-methods -- Add optional parameter '--xunit-dump-suite-output'. If enabled drops TestSuite-level sysout/syserr to XUnit report. +- Add optional parameter `--xunit-dump-suite-output`. If enabled drops TestSuite-level sysout/syserr to XUnit report. ## 0.4.3 -- Add XUnit plugin 'lode_runner.plugins.ClassSkipper'. Allows skip TestClasses with no setUpClass calls +- Add XUnit plugin `lode_runner.plugins.ClassSkipper`. Allows skip TestClasses with no setUpClass calls ## 0.4.2 -- Skip 'nose.multiprocess' testcases dirung merging xml files +- Skip `nose.multiprocess` testcases during merging xml files ## 0.4.1 diff --git a/lode_runner/lode_merge_xunit.py b/lode_runner/lode_merge_xunit.py index e99153c..5af62d0 100644 --- a/lode_runner/lode_merge_xunit.py +++ b/lode_runner/lode_merge_xunit.py @@ -36,8 +36,13 @@ def modify_suite(suite, testcase, value): for testcase in suite: if "nose.plugins.multiprocess" in testcase.get("classname", ""): continue + candidates = base_root.findall(xpath % testcase.get('classname')) - matching_testcase = next(t for t in candidates if t.get('name') == testcase.get('name')) + try: + matching_testcase = next(t for t in candidates if t.get('name') == testcase.get('name')) + except StopIteration: + matching_testcase = None + if matching_testcase is not None: modify_suite(base_root, matching_testcase, -1) base_root.remove(matching_testcase) @@ -47,7 +52,9 @@ def modify_suite(suite, testcase, value): return base_root -get_roots = lambda reports: [ElementTree.parse(r).getroot() for r in reports] + +def get_roots(reports): + return [ElementTree.parse(r).getroot() for r in reports] def merge_reports(reports, output): @@ -63,5 +70,6 @@ def main(): merge_reports(reports, output) + if __name__ == "__main__": main() diff --git a/lode_runner/plugins/xunit.py b/lode_runner/plugins/xunit.py index 0c7b004..1053159 100644 --- a/lode_runner/plugins/xunit.py +++ b/lode_runner/plugins/xunit.py @@ -7,6 +7,7 @@ from lode_runner.plugins import force_unicode_decorator +from nose.suite import ContextSuite from nose.plugins.xunit import Xunit as NoseXunit, force_unicode from nose.plugins.base import Plugin @@ -86,6 +87,24 @@ def stopContext(self, context): self._dump_suite_output() super(Xunit, self).stopContext(context) + def _get_tests_list(self, test): + """Get separate tests list if `test` is ContextSuite""" + if isinstance(test, ContextSuite): + res = [] + for t in test._tests: + res += self._get_tests_list(t) + return res + + return [test] + + def addError(self, test, err, capt=None): + for t in self._get_tests_list(test): + super(Xunit, self).addError(t, err, capt) + + def addFailure(self, test, err, capt=None, tb_info=None): + for t in self._get_tests_list(test): + super(Xunit, self).addFailure(t, err, capt, tb_info) + def report(self, stream): """Writes an Xunit-formatted XML file diff --git a/setup.py b/setup.py index ed1704c..2c807a3 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ setup( name='lode_runner', url='https://github.com/2gis/lode_runner', - version='0.4.5', + version='0.4.6', description='Nosetests runner plugins package', long_description='', author='Igor Pavlov',