Skip to content

Commit

Permalink
Add support for JSON reporter
Browse files Browse the repository at this point in the history
This exposes an additional reporter that's provided by coverage.py. THe
implementation is basically a carbon copy of the code that powers the
XML implementation.
  • Loading branch information
mwg-rea authored and ionelmc committed May 21, 2023
1 parent dec02ab commit f3d8d83
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 7 deletions.
4 changes: 2 additions & 2 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ The complete list of command line options is:

--cov=PATH Measure coverage for filesystem path. (multi-allowed)
--cov-report=type Type of report to generate: term, term-missing,
annotate, html, xml, lcov (multi-allowed). term, term-
annotate, html, xml, json, lcov (multi-allowed). term, term-
missing may be followed by ":skip-covered". annotate,
html, xml and lcov may be followed by ":DEST" where DEST
html, xml, json and lcov may be followed by ":DEST" where DEST
specifies the output location. Use --cov-report= to
not generate any output.
--cov-config=path Config file for coverage. Default: .coveragerc
Expand Down
6 changes: 4 additions & 2 deletions docs/reporting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Reporting

It is possible to generate any combination of the reports for a single test run.

The available reports are terminal (with or without missing line numbers shown), HTML, XML, LCOV and
The available reports are terminal (with or without missing line numbers shown), HTML, XML, JSON, LCOV and
annotated source code.

The terminal report without line numbers (default)::
Expand Down Expand Up @@ -53,16 +53,18 @@ These four report options output to files without showing anything on the termin

pytest --cov-report html
--cov-report xml
--cov-report json
--cov-report lcov
--cov-report annotate
--cov=myproj tests/

The output location for each of these reports can be specified. The output location for the XML and LCOV
The output location for each of these reports can be specified. The output location for the XML, JSON and LCOV
report is a file. Where as the output location for the HTML and annotated source code reports are
directories::

pytest --cov-report html:cov_html
--cov-report xml:cov.xml
--cov-report json:cov.json
--cov-report lcov:cov.info
--cov-report annotate:cov_annotate
--cov=myproj tests/
Expand Down
7 changes: 7 additions & 0 deletions src/pytest_cov/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,13 @@ def summary(self, stream):
total = self.cov.xml_report(ignore_errors=True, outfile=output)
stream.write('Coverage XML written to file %s\n' % (self.cov.config.xml_output if output is None else output))

# Produce json report if wanted
if 'json' in self.cov_report:
output = self.cov_report['json']
with _backup(self.cov, "config"):
total = self.cov.json_report(ignore_errors=True, outfile=output)
stream.write('Coverage JSON written to file %s\n' % (self.cov.config.json_output if output is None else output))

# Produce lcov report if wanted.
if 'lcov' in self.cov_report:
output = self.cov_report['lcov']
Expand Down
6 changes: 3 additions & 3 deletions src/pytest_cov/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class CovReportWarning(PytestCovWarning):


def validate_report(arg):
file_choices = ['annotate', 'html', 'xml', 'lcov']
file_choices = ['annotate', 'html', 'xml', 'json', 'lcov']
term_choices = ['term', 'term-missing']
term_modifier_choices = ['skip-covered']
all_choices = term_choices + file_choices
Expand Down Expand Up @@ -99,9 +99,9 @@ def pytest_addoption(parser):
group.addoption('--cov-report', action=StoreReport, default={},
metavar='TYPE', type=validate_report,
help='Type of report to generate: term, term-missing, '
'annotate, html, xml, lcov (multi-allowed). '
'annotate, html, xml, json, lcov (multi-allowed). '
'term, term-missing may be followed by ":skip-covered". '
'annotate, html, xml and lcov may be followed by ":DEST" '
'annotate, html, xml, json and lcov may be followed by ":DEST" '
'where DEST specifies the output location. '
'Use --cov-report= to not generate any output.')
group.addoption('--cov-config', action='store', default='.coveragerc',
Expand Down
18 changes: 18 additions & 0 deletions tests/test_pytest_cov.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ def test_foo(cov):
PARENT_SCRIPT_RESULT = '9 * 100%'
DEST_DIR = 'cov_dest'
XML_REPORT_NAME = 'cov.xml'
JSON_REPORT_NAME = 'cov.json'
LCOV_REPORT_NAME = 'cov.info'

xdist_params = pytest.mark.parametrize('opts', [
Expand Down Expand Up @@ -346,6 +347,23 @@ def test_xml_output_dir(testdir):
assert result.ret == 0


def test_json_output_dir(testdir):
script = testdir.makepyfile(SCRIPT)

result = testdir.runpytest('-v',
'--cov=%s' % script.dirpath(),
'--cov-report=json:' + JSON_REPORT_NAME,
script)

result.stdout.fnmatch_lines([
'*- coverage: platform *, python * -*',
'Coverage JSON written to file ' + JSON_REPORT_NAME,
'*10 passed*',
])
assert testdir.tmpdir.join(JSON_REPORT_NAME).check()
assert result.ret == 0


@pytest.mark.skipif("coverage.version_info < (6, 3)")
def test_lcov_output_dir(testdir):
script = testdir.makepyfile(SCRIPT)
Expand Down

0 comments on commit f3d8d83

Please sign in to comment.