From c6cb24f37763ab677e4910099c0f55a10878c533 Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Mon, 24 Nov 2014 20:17:47 +0100 Subject: [PATCH 1/8] added support for `cov-min` option to require coverage percentage --- cov-core/cov_core.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cov-core/cov_core.py b/cov-core/cov_core.py index b9618050..2b895245 100644 --- a/cov-core/cov_core.py +++ b/cov-core/cov_core.py @@ -81,6 +81,8 @@ def summary(self, stream): if self.cov_report == ['']: return + total = 0 + # Output coverage section header. if len(self.node_descs) == 1: self.sep(stream, '-', 'coverage: %s' % ''.join(self.node_descs)) @@ -92,21 +94,21 @@ def summary(self, stream): # Produce terminal report if wanted. if 'term' in self.cov_report or 'term-missing' in self.cov_report: show_missing = 'term-missing' in self.cov_report - self.cov.report(show_missing=show_missing, ignore_errors=True, file=stream) + total = self.cov.report(show_missing=show_missing, ignore_errors=True, file=stream) # Produce annotated source code report if wanted. if 'annotate' in self.cov_report: - self.cov.annotate(ignore_errors=True) + total = self.cov.annotate(ignore_errors=True) stream.write('Coverage annotated source written next to source\n') # Produce html report if wanted. if 'html' in self.cov_report: - self.cov.html_report(ignore_errors=True) + total = self.cov.html_report(ignore_errors=True) stream.write('Coverage HTML written to dir %s\n' % self.cov.config.html_dir) # Produce xml report if wanted. if 'xml' in self.cov_report: - self.cov.xml_report(ignore_errors=True) + total = self.cov.xml_report(ignore_errors=True) stream.write('Coverage XML written to file %s\n' % self.cov.config.xml_output) # Report on any failed slaves. @@ -117,6 +119,8 @@ def summary(self, stream): for node in self.failed_slaves: stream.write('%s\n' % node.gateway.id) + return total + class Central(CovController): """Implementation for centralised operation.""" @@ -140,7 +144,6 @@ def finish(self): node_desc = self.get_node_desc(sys.platform, sys.version_info) self.node_descs.add(node_desc) - class DistMaster(CovController): """Implementation for distributed master.""" From 8f679db735ab99f66808e79d4e401996a9191ec0 Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Mon, 24 Nov 2014 11:13:49 +0100 Subject: [PATCH 2/8] added support for `cov-min` option to require coverage percentage --- pytest-cov/pytest_cov.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pytest-cov/pytest_cov.py b/pytest-cov/pytest_cov.py index c9c6db4f..c27aca9e 100644 --- a/pytest-cov/pytest_cov.py +++ b/pytest-cov/pytest_cov.py @@ -8,6 +8,10 @@ import cov_core_init +class CoverageError(Exception): + '''Indicates that our coverage is too low''' + + def pytest_addoption(parser): """Add options to control coverage.""" @@ -30,6 +34,9 @@ def pytest_addoption(parser): dest='no_cov_on_fail', help='do not report coverage if test run fails, ' 'default: False') + group.addoption('--cov-min', action='store', metavar='MIN', type='int', + help='Fail if the total coverage is less than MIN.') + @pytest.mark.tryfirst @@ -135,7 +142,11 @@ def pytest_terminal_summary(self, terminalreporter): if self.cov_controller is None: return if not (self.failed and self.options.no_cov_on_fail): - self.cov_controller.summary(terminalreporter._tw) + total = self.cov_controller.summary(terminalreporter._tw) + if total < self.options.cov_min: + raise CoverageError(('Required test coverage of %d%% not ' + 'reached. Total coverage: %.2f%%') + % (self.options.cov_min, total)) def pytest_runtest_setup(self, item): if os.getpid() != self.pid: From af39229cc630793d5c84732d504c7e03f117fbdc Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Mon, 24 Nov 2014 21:03:36 +0100 Subject: [PATCH 3/8] fixed merge flake8 errors --- cov-core/cov_core.py | 1 + pytest-cov/pytest_cov.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cov-core/cov_core.py b/cov-core/cov_core.py index 2b895245..d375f783 100644 --- a/cov-core/cov_core.py +++ b/cov-core/cov_core.py @@ -144,6 +144,7 @@ def finish(self): node_desc = self.get_node_desc(sys.platform, sys.version_info) self.node_descs.add(node_desc) + class DistMaster(CovController): """Implementation for distributed master.""" diff --git a/pytest-cov/pytest_cov.py b/pytest-cov/pytest_cov.py index c27aca9e..2a42e05f 100644 --- a/pytest-cov/pytest_cov.py +++ b/pytest-cov/pytest_cov.py @@ -38,7 +38,6 @@ def pytest_addoption(parser): help='Fail if the total coverage is less than MIN.') - @pytest.mark.tryfirst def pytest_load_initial_conftests(early_config, parser, args): ns = parser.parse_known_args(args) From 50a6672ba96ef82b41ce0916e68fd61fc48feb64 Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Mon, 24 Nov 2014 22:51:54 +0100 Subject: [PATCH 4/8] added python 3 support --- pytest-cov/pytest_cov.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pytest-cov/pytest_cov.py b/pytest-cov/pytest_cov.py index a179eb0f..d13fac57 100644 --- a/pytest-cov/pytest_cov.py +++ b/pytest-cov/pytest_cov.py @@ -155,7 +155,8 @@ def pytest_terminal_summary(self, terminalreporter): return if not (self.failed and self.options.no_cov_on_fail): total = self.cov_controller.summary(terminalreporter.writer) - if total < self.options.cov_min: + cov_min = self.options.cov_min + if cov_min is not None and total < cov_min: raise CoverageError(('Required test coverage of %d%% not ' 'reached. Total coverage: %.2f%%') % (self.options.cov_min, total)) From c967ef2927c02461d66ca5bddf93debff3a4777b Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Mon, 24 Nov 2014 22:52:00 +0100 Subject: [PATCH 5/8] added tests --- pytest-cov/test_pytest_cov.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pytest-cov/test_pytest_cov.py b/pytest-cov/test_pytest_cov.py index 6da07dd9..10857c47 100644 --- a/pytest-cov/test_pytest_cov.py +++ b/pytest-cov/test_pytest_cov.py @@ -113,6 +113,30 @@ def test_central(testdir): assert result.ret == 0 +def test_central_cov_min_100(testdir): + script = testdir.makepyfile(SCRIPT) + + result = testdir.runpytest('-v', + '--cov', '--cov-source=%s' % script.dirpath(), + '--cov-report=term-missing', + '--cov-min=100', + script) + + assert result.ret == 1 + + +def test_central_cov_min_50(testdir): + script = testdir.makepyfile(SCRIPT) + + result = testdir.runpytest('-v', + '--cov', '--cov-source=%s' % script.dirpath(), + '--cov-report=term-missing', + '--cov-min=50', + script) + + assert result.ret == 0 + + def test_central_nonspecific(testdir): script = testdir.makepyfile(SCRIPT) From f978add780bbb0583fdb2b7f879191f8d29e235a Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Mon, 24 Nov 2014 22:57:43 +0100 Subject: [PATCH 6/8] added test for no-report --- pytest-cov/test_pytest_cov.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pytest-cov/test_pytest_cov.py b/pytest-cov/test_pytest_cov.py index 10857c47..a6c2ee76 100644 --- a/pytest-cov/test_pytest_cov.py +++ b/pytest-cov/test_pytest_cov.py @@ -137,6 +137,17 @@ def test_central_cov_min_50(testdir): assert result.ret == 0 +def test_central_cov_min_no_report(testdir): + script = testdir.makepyfile(SCRIPT) + + result = testdir.runpytest('-v', + '--cov', '--cov-source=%s' % script.dirpath(), + '--cov-min=50', + script) + + assert result.ret == 0 + + def test_central_nonspecific(testdir): script = testdir.makepyfile(SCRIPT) From f24ec87a84cf13334ff91cfc25bb5ebdfb8fc2f8 Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Mon, 24 Nov 2014 22:58:52 +0100 Subject: [PATCH 7/8] renamed tests for clarity --- pytest-cov/test_pytest_cov.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pytest-cov/test_pytest_cov.py b/pytest-cov/test_pytest_cov.py index a6c2ee76..36aae5a6 100644 --- a/pytest-cov/test_pytest_cov.py +++ b/pytest-cov/test_pytest_cov.py @@ -113,7 +113,7 @@ def test_central(testdir): assert result.ret == 0 -def test_central_cov_min_100(testdir): +def test_cov_min_100(testdir): script = testdir.makepyfile(SCRIPT) result = testdir.runpytest('-v', @@ -125,7 +125,7 @@ def test_central_cov_min_100(testdir): assert result.ret == 1 -def test_central_cov_min_50(testdir): +def test_cov_min_50(testdir): script = testdir.makepyfile(SCRIPT) result = testdir.runpytest('-v', @@ -137,7 +137,7 @@ def test_central_cov_min_50(testdir): assert result.ret == 0 -def test_central_cov_min_no_report(testdir): +def test_cov_min_no_report(testdir): script = testdir.makepyfile(SCRIPT) result = testdir.runpytest('-v', From f80178d8e72e28c12cf968355129d8ea8bbc7ed2 Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Tue, 25 Nov 2014 10:45:23 +0100 Subject: [PATCH 8/8] added tests for --cov-report="" --- cov-core/cov_core.py | 8 +++++--- pytest-cov/pytest_cov.py | 1 + pytest-cov/test_pytest_cov.py | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/cov-core/cov_core.py b/cov-core/cov_core.py index d375f783..dd5a2b57 100644 --- a/cov-core/cov_core.py +++ b/cov-core/cov_core.py @@ -78,11 +78,13 @@ def sep(stream, s, txt): def summary(self, stream): """Produce coverage reports.""" - if self.cov_report == ['']: - return - total = 0 + if self.cov_report == ['']: + with open(os.devnull, 'w') as null: + total = self.cov.report(show_missing=True, ignore_errors=True, file=null) + return total + # Output coverage section header. if len(self.node_descs) == 1: self.sep(stream, '-', 'coverage: %s' % ''.join(self.node_descs)) diff --git a/pytest-cov/pytest_cov.py b/pytest-cov/pytest_cov.py index d13fac57..edfe73b2 100644 --- a/pytest-cov/pytest_cov.py +++ b/pytest-cov/pytest_cov.py @@ -155,6 +155,7 @@ def pytest_terminal_summary(self, terminalreporter): return if not (self.failed and self.options.no_cov_on_fail): total = self.cov_controller.summary(terminalreporter.writer) + assert total is not None, 'Test coverage should never be `None`' cov_min = self.options.cov_min if cov_min is not None and total < cov_min: raise CoverageError(('Required test coverage of %d%% not ' diff --git a/pytest-cov/test_pytest_cov.py b/pytest-cov/test_pytest_cov.py index 36aae5a6..5dacc1c2 100644 --- a/pytest-cov/test_pytest_cov.py +++ b/pytest-cov/test_pytest_cov.py @@ -142,6 +142,7 @@ def test_cov_min_no_report(testdir): result = testdir.runpytest('-v', '--cov', '--cov-source=%s' % script.dirpath(), + '--cov-report=', '--cov-min=50', script)