From cc56caa1e8246749c94ecb32adbe8d52c6201e22 Mon Sep 17 00:00:00 2001 From: Martin Gaitan Date: Fri, 26 Jul 2019 17:51:18 -0300 Subject: [PATCH 1/3] Support float values for --cov-fail-under. It only show the decimal part if needed --- src/pytest_cov/plugin.py | 18 +++++++++++------- tests/test_pytest_cov.py | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index b57b569b..b238818a 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -73,7 +73,7 @@ def pytest_addoption(parser): group.addoption('--no-cov', action='store_true', default=False, help='Disable coverage report completely (useful for debuggers). ' 'Default: False') - group.addoption('--cov-fail-under', action='store', metavar='MIN', type=int, + group.addoption('--cov-fail-under', action='store', metavar='MIN', type=float, help='Fail if the total coverage is less than MIN.') group.addoption('--cov-append', action='store_true', default=False, help='Do not delete coverage but append to current. ' @@ -263,20 +263,24 @@ def pytest_terminal_summary(self, terminalreporter): terminalreporter.write('\n' + self.cov_report.getvalue() + '\n') - if self.options.cov_fail_under is not None and self.options.cov_fail_under > 0: - if self.cov_total < self.options.cov_fail_under: + fail_under = self.options.cov_fail_under + if fail_under is not None and fail_under > 0: + str_fail_under = str( + round(fail_under, 2) if fail_under % 1 else int(fail_under) + ) + if self.cov_total < fail_under: markup = {'red': True, 'bold': True} message = ( - 'FAIL Required test coverage of %d%% not ' + 'FAIL Required test coverage of %s%% not ' 'reached. Total coverage: %.2f%%\n' - % (self.options.cov_fail_under, self.cov_total) + % (str_fail_under, self.cov_total) ) else: markup = {'green': True} message = ( - 'Required test coverage of %d%% ' + 'Required test coverage of %s%% ' 'reached. Total coverage: %.2f%%\n' - % (self.options.cov_fail_under, self.cov_total) + % (str_fail_under, self.cov_total) ) terminalreporter.write(message, **markup) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 7ef28122..f5217e70 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -340,6 +340,20 @@ def test_cov_min_50(testdir): ]) +def test_cov_min_float_value(testdir): + script = testdir.makepyfile(SCRIPT) + + result = testdir.runpytest('-v', + '--cov=%s' % script.dirpath(), + '--cov-report=term-missing', + '--cov-fail-under=51.03', + script) + assert result.ret == 0 + result.stdout.fnmatch_lines([ + 'Required test coverage of 51.03% reached. Total coverage: *%' + ]) + + def test_cov_min_no_report(testdir): script = testdir.makepyfile(SCRIPT) From 5befa8a69370accf22008ba216c80abed1eb271b Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Thu, 29 Aug 2019 14:54:12 +0100 Subject: [PATCH 2/3] try parsing cov-fail-under as int then float --- src/pytest_cov/plugin.py | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/pytest_cov/plugin.py b/src/pytest_cov/plugin.py index f1955088..d84a6dbc 100644 --- a/src/pytest_cov/plugin.py +++ b/src/pytest_cov/plugin.py @@ -41,6 +41,13 @@ def validate_report(arg): return values +def validate_fail_under(num_str): + try: + return int(num_str) + except ValueError: + return float(num_str) + + class StoreReport(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): report_type, file = values @@ -73,7 +80,8 @@ def pytest_addoption(parser): group.addoption('--no-cov', action='store_true', default=False, help='Disable coverage report completely (useful for debuggers). ' 'Default: False') - group.addoption('--cov-fail-under', action='store', metavar='MIN', type=float, + group.addoption('--cov-fail-under', action='store', metavar='MIN', + type=validate_fail_under, help='Fail if the total coverage is less than MIN.') group.addoption('--cov-append', action='store_true', default=False, help='Do not delete coverage but append to current. ' @@ -265,25 +273,19 @@ def pytest_terminal_summary(self, terminalreporter): terminalreporter.write('\n' + self.cov_report.getvalue() + '\n') - fail_under = self.options.cov_fail_under - if fail_under is not None and fail_under > 0: - str_fail_under = str( - round(fail_under, 2) if fail_under % 1 else int(fail_under) - ) - if self.cov_total < fail_under: - markup = {'red': True, 'bold': True} - message = ( - 'FAIL Required test coverage of %s%% not ' - 'reached. Total coverage: %.2f%%\n' - % (str_fail_under, self.cov_total) - ) - else: - markup = {'green': True} - message = ( - 'Required test coverage of %s%% ' - 'reached. Total coverage: %.2f%%\n' - % (str_fail_under, self.cov_total) + if self.options.cov_fail_under is not None and self.options.cov_fail_under > 0: + failed = self.cov_total < self.options.cov_fail_under + markup = {'red': True, 'bold': True} if failed else {'green': True} + message = ( + '{fail}Required test coverage of {required}% {reached}. ' + 'Total coverage: {actual:.2f}%\n' + .format( + required=self.options.cov_fail_under, + actual=self.cov_total, + fail="FAIL " if failed else "", + reached="not reached" if failed else "reached" ) + ) terminalreporter.write(message, **markup) def pytest_runtest_setup(self, item): From 68e6f4d45426d9d48869f78ea8632d0e4f428672 Mon Sep 17 00:00:00 2001 From: Thomas Grainger Date: Fri, 30 Aug 2019 10:54:58 +0100 Subject: [PATCH 3/3] test cov-fail-under float pass and fail --- tests/test_pytest_cov.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/test_pytest_cov.py b/tests/test_pytest_cov.py index 0b0da6d8..e745c956 100644 --- a/tests/test_pytest_cov.py +++ b/tests/test_pytest_cov.py @@ -349,11 +349,25 @@ def test_cov_min_float_value(testdir): result = testdir.runpytest('-v', '--cov=%s' % script.dirpath(), '--cov-report=term-missing', - '--cov-fail-under=51.03', + '--cov-fail-under=88.88', script) assert result.ret == 0 result.stdout.fnmatch_lines([ - 'Required test coverage of 51.03% reached. Total coverage: *%' + 'Required test coverage of 88.88% reached. Total coverage: 88.89%' + ]) + + +def test_cov_min_float_value_not_reached(testdir): + script = testdir.makepyfile(SCRIPT) + + result = testdir.runpytest('-v', + '--cov=%s' % script.dirpath(), + '--cov-report=term-missing', + '--cov-fail-under=88.89', + script) + assert result.ret == 1 + result.stdout.fnmatch_lines([ + 'FAIL Required test coverage of 88.89% not reached. Total coverage: 88.89%' ])