mirror of
https://github.com/PyCQA/flake8.git
synced 2026-04-07 13:36:54 +00:00
Implemented output to JUnit XML file
This commit is contained in:
parent
0c09268247
commit
0819a14b2e
3 changed files with 81 additions and 1 deletions
|
|
@ -57,7 +57,7 @@ class Manager(object):
|
|||
together and make our output deterministic.
|
||||
"""
|
||||
|
||||
def __init__(self, style_guide, arguments, checker_plugins):
|
||||
def __init__(self, style_guide, arguments, checker_plugins, junit_xml_report):
|
||||
"""Initialize our Manager instance.
|
||||
|
||||
:param style_guide:
|
||||
|
|
@ -70,11 +70,14 @@ class Manager(object):
|
|||
The plugins representing checks parsed from entry-points.
|
||||
:type checker_plugins:
|
||||
flake8.plugins.manager.Checkers
|
||||
:param str junit_xml_report:
|
||||
Filename to write a JUnit XML report to
|
||||
"""
|
||||
self.arguments = arguments
|
||||
self.style_guide = style_guide
|
||||
self.options = style_guide.options
|
||||
self.checks = checker_plugins
|
||||
self.junit_xml_report = junit_xml_report
|
||||
self.jobs = self._job_count()
|
||||
self.process_queue = None
|
||||
self.results_queue = None
|
||||
|
|
@ -292,13 +295,79 @@ class Manager(object):
|
|||
tuple(int, int)
|
||||
"""
|
||||
results_reported = results_found = 0
|
||||
all_results = {}
|
||||
for checker in self.checkers:
|
||||
if checker.filename not in all_results:
|
||||
all_results[checker.filename] = {'checker': checker}
|
||||
results = sorted(checker.results, key=lambda tup: (tup[1], tup[2]))
|
||||
all_results[checker.filename]['errors'] = results
|
||||
results_reported += self._handle_results(checker.display_name,
|
||||
results)
|
||||
results_found += len(results)
|
||||
|
||||
# Output JUnit XML
|
||||
self.report_junit_xml(all_results)
|
||||
|
||||
return (results_found, results_reported)
|
||||
|
||||
def report_junit_xml(self, all_results):
|
||||
"""
|
||||
Report all results to a JUnit XML file
|
||||
|
||||
:param dict all_results: A dictionary containing all results
|
||||
"""
|
||||
# If no junit_xml_report file was provided, just skip this
|
||||
if not self.junit_xml_report:
|
||||
return
|
||||
|
||||
testcase_success_template = '<testcase classname="{classname}" file="{filename}" line="{line_number}" ' \
|
||||
'name="{name}" time="{time_elapsed}"/>'
|
||||
testcase_failure_template = '<testcase classname="{classname}" file="{filename}" line="{line_number}" ' \
|
||||
'name="{name}" time="{time_elapsed}"><failure message="{short_message}">' \
|
||||
'{long_message}</failure></testcase>'
|
||||
testsuite_template = '<testsuite errors="{num_errors}" failures="{num_failures}" name="flake8" ' \
|
||||
'skips="{num_skips}" tests="{num_tests}" time="{time_elapsed}">' \
|
||||
'\n{testcase_nodes}\n</testsuite>'
|
||||
|
||||
testcase_nodes = []
|
||||
num_failures = 0
|
||||
num_files = len(all_results)
|
||||
for filename in sorted(all_results.keys()):
|
||||
errors = all_results[filename]['errors']
|
||||
if errors:
|
||||
num_failures += 1
|
||||
for error_code, line_number, column, text, physical_line in errors:
|
||||
testcase_nodes.append(testcase_failure_template.format(**{
|
||||
'classname': '', # n.a.
|
||||
'filename': filename,
|
||||
'line_number': line_number,
|
||||
'name': '%s: %s' % (filename, error_code),
|
||||
'time_elapsed': '0.1', # Not yet measured?
|
||||
'short_message': text,
|
||||
'long_message': 'lineno: %d, column: %d, code: %s, error: %s\n>>%s' % (
|
||||
line_number, column, error_code, text, physical_line)
|
||||
}))
|
||||
else:
|
||||
testcase_nodes.append(testcase_success_template.format(**{
|
||||
'classname': '', # n.a.
|
||||
'filename': filename,
|
||||
'line_number': 1,
|
||||
'name': filename,
|
||||
'time_elapsed': '0.1', # Not yet measured?
|
||||
}))
|
||||
|
||||
ouput = testsuite_template.format(**{
|
||||
'num_errors': 0,
|
||||
'num_failures': num_failures,
|
||||
'num_skips': 0,
|
||||
'num_tests': num_files,
|
||||
'time_elapsed': 1,
|
||||
'testcase_nodes': '\n'.join(testcase_nodes)
|
||||
})
|
||||
|
||||
with open(self.junit_xml_report, 'w') as junit_xml_file:
|
||||
junit_xml_file.write(ouput)
|
||||
|
||||
def run_parallel(self):
|
||||
"""Run the checkers in parallel."""
|
||||
LOG.info('Starting %d process workers', self.jobs)
|
||||
|
|
|
|||
|
|
@ -108,6 +108,9 @@ class Application(object):
|
|||
#: The parsed diff information
|
||||
self.parsed_diff = {}
|
||||
|
||||
#: JUnit XML
|
||||
self.junit_xml_report = preliminary_opts.output_xmlfile
|
||||
|
||||
def exit(self):
|
||||
# type: () -> NoneType
|
||||
"""Handle finalization and exiting the program.
|
||||
|
|
@ -221,6 +224,7 @@ class Application(object):
|
|||
style_guide=self.guide,
|
||||
arguments=self.args,
|
||||
checker_plugins=self.check_plugins,
|
||||
junit_xml_report=self.junit_xml_report
|
||||
)
|
||||
|
||||
def run_checks(self, files=None):
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ def register_default_options(option_manager):
|
|||
- ``--exit-zero``
|
||||
- ``-j``/``--jobs``
|
||||
- ``--output-file``
|
||||
- ``--output-xmlfile``
|
||||
- ``--tee``
|
||||
- ``--append-config``
|
||||
- ``--config``
|
||||
|
|
@ -175,6 +176,12 @@ def register_default_options(option_manager):
|
|||
help='Redirect report to a file.',
|
||||
)
|
||||
|
||||
add_option(
|
||||
'--output-xmlfile', default=None, type='string', parse_from_config=True,
|
||||
# callback=callbacks.redirect_stdout,
|
||||
help='Create JUnit XML report.',
|
||||
)
|
||||
|
||||
add_option(
|
||||
'--tee', default=False, parse_from_config=True, action='store_true',
|
||||
help='Write to stdout and output-file.',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue