From 58e0633eaee55ddefbdf84c833b4e179347c122d Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Mon, 9 Nov 2015 06:11:42 -0500 Subject: [PATCH] This script is now in github.com/nedbat/xunit_tools --- scripts/summarize_test_results.py | 127 ------------------------------ 1 file changed, 127 deletions(-) delete mode 100755 scripts/summarize_test_results.py diff --git a/scripts/summarize_test_results.py b/scripts/summarize_test_results.py deleted file mode 100755 index 32f1879ed4..0000000000 --- a/scripts/summarize_test_results.py +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python -"""Summarize the results of running all the tests. - -See the report_all_files docstring for details, or run this with --help. - -""" - -import collections -import os - -import click -from lxml import etree - - -@click.command() -@click.option("--errors/--no-errors", help="Show details of errors") -@click.option("--names/--no-names", help="Show all test names") -@click.option("--outcomes/--no-outcomes", help="Show pass/fail/error with names") -@click.argument("start", default="reports") -def report_all_files(errors, names, outcomes, start): - """Find all the nosetests.xml files, and report on them. - - For every nosetests.xml file found, prints a summary of the number of - tests, fails, errors, etc. If --details is used, then the error messages - from all of the fails and errors will be shown, most frequent first, with a - count of how many tests failed for that reason. - - """ - totals = TestResults() - for dirpath, _, filenames in os.walk(start): - if "nosetests.xml" in filenames: - results = report_file( - os.path.join(dirpath, "nosetests.xml"), - errors=errors, - names=names, - outcomes=outcomes, - ) - totals += results - - print "\nTotals:\n{}".format(totals) - - -class Summable(object): - """An object whose attributes can be added together easily. - - Subclass this and define `fields` on your derived class. - - """ - def __init__(self): - for name in self.fields: - setattr(self, name, 0) - - @classmethod - def from_element(cls, element): - """Construct a Summable from an xml element with the same attributes.""" - self = cls() - for name in self.fields: - setattr(self, name, int(element.get(name))) - return self - - def __add__(self, other): - result = type(self)() - for name in self.fields: - setattr(result, name, getattr(self, name) + getattr(other, name)) - return result - - -class TestResults(Summable): - """A test result, makeable from a nosetests.xml element.""" - - fields = ["tests", "errors", "failures", "skip"] - - def __str__(self): - msg = "{0.tests:4d} tests, {0.errors} errors, {0.failures} failures, {0.skip} skipped" - return msg.format(self) - - -def error_line_from_error_element(element): - """Given an element, get the important error line from it.""" - return element.get("message").splitlines()[0] - - -def report_file(path, errors, names, outcomes): - """Report on one nosetests.xml file.""" - print "\n{}".format(path) - with open(path) as xml_file: - tree = etree.parse(xml_file) # pylint: disable=no-member - suite = tree.xpath("/testsuite")[0] - - results = TestResults.from_element(suite) - print results - - if errors: - errors = collections.Counter() - for error_element in tree.xpath(".//error|.//failure"): - errors[error_line_from_error_element(error_element)] += 1 - - if errors: - print "" - for error_message, number in errors.most_common(): - print "{0:4d}: {1}".format(number, error_message) - - if names: - for testcase in tree.xpath(".//testcase"): - if outcomes: - result = testcase.xpath("*") - if result: - outcome = result[0].tag - if outcome == "system-out": - outcome = "." - else: - outcome = outcome[0].upper() - else: - outcome = "." - else: - outcome = "" - print " {outcome} {classname}.{name}".format( - outcome=outcome, - classname=testcase.get("classname"), - name=testcase.get("name"), - ) - - return results - - -if __name__ == "__main__": - report_all_files() # pylint: disable=no-value-for-parameter