diff options
-rw-r--r-- | functional_tests/support/coverage2/blah.py | 6 | ||||
-rw-r--r-- | functional_tests/support/coverage2/moo.py | 2 | ||||
-rw-r--r-- | functional_tests/support/coverage2/tests/test_covered.py | 8 | ||||
-rw-r--r-- | functional_tests/test_coverage_plugin.py | 47 | ||||
-rw-r--r-- | nose/plugins/cover.py | 25 |
5 files changed, 85 insertions, 3 deletions
diff --git a/functional_tests/support/coverage2/blah.py b/functional_tests/support/coverage2/blah.py new file mode 100644 index 0000000..ef6657c --- /dev/null +++ b/functional_tests/support/coverage2/blah.py @@ -0,0 +1,6 @@ +def dostuff(): + print 'hi' + + +def notcov(): + print 'not covered' diff --git a/functional_tests/support/coverage2/moo.py b/functional_tests/support/coverage2/moo.py new file mode 100644 index 0000000..7ad09bf --- /dev/null +++ b/functional_tests/support/coverage2/moo.py @@ -0,0 +1,2 @@ +def moo(): + print 'covered' diff --git a/functional_tests/support/coverage2/tests/test_covered.py b/functional_tests/support/coverage2/tests/test_covered.py new file mode 100644 index 0000000..034f984 --- /dev/null +++ b/functional_tests/support/coverage2/tests/test_covered.py @@ -0,0 +1,8 @@ +import blah +import moo + +def test_blah(): + blah.dostuff() + +def test_moo(): + moo.dostuff() diff --git a/functional_tests/test_coverage_plugin.py b/functional_tests/test_coverage_plugin.py index d1b2632..717f13a 100644 --- a/functional_tests/test_coverage_plugin.py +++ b/functional_tests/test_coverage_plugin.py @@ -11,7 +11,7 @@ support = os.path.join(os.path.dirname(__file__), 'support') class TestCoveragePlugin(PluginTester, unittest.TestCase): activate = "--with-coverage" - args = ['-v', '--cover-package=blah', '--cover-html'] + args = ['-v', '--cover-package=blah', '--cover-html', '--cover-min-percentage', '25'] plugins = [Coverage()] suitepath = os.path.join(support, 'coverage') @@ -25,13 +25,54 @@ class TestCoveragePlugin(PluginTester, unittest.TestCase): super(TestCoveragePlugin, self).setUp() def runTest(self): - self.assertTrue("blah 4 1 75% 6" in self.output) + self.assertTrue("blah 4 3 25% 1" in self.output) self.assertTrue("Ran 1 test in""" in self.output) # Assert coverage html report exists self.assertTrue(os.path.exists(os.path.join(self.cover_html_dir, - 'index.html'))) + 'index.html'))) # Assert coverage data is saved self.assertTrue(os.path.exists(self.cover_file)) + +class TestCoverageMinPercentagePlugin(PluginTester, unittest.TestCase): + activate = "--with-coverage" + args = ['-v', '--cover-package=blah', '--cover-min-percentage', '100'] + plugins = [Coverage()] + suitepath = os.path.join(support, 'coverage') + + def setUp(self): + self.cover_file = os.path.join(os.getcwd(), '.coverage') + self.cover_html_dir = os.path.join(os.getcwd(), 'cover') + if os.path.exists(self.cover_file): + os.unlink(self.cover_file) + if os.path.exists(self.cover_html_dir): + shutil.rmtree(self.cover_html_dir) + self.assertRaises(SystemExit, + super(TestCoverageMinPercentagePlugin, self).setUp) + + def runTest(self): + pass + + +class TestCoverageMinPercentageTOTALPlugin(PluginTester, unittest.TestCase): + activate = "--with-coverage" + args = ['-v', '--cover-package=blah', '--cover-package=moo', + '--cover-min-percentage', '100'] + plugins = [Coverage()] + suitepath = os.path.join(support, 'coverage2') + + def setUp(self): + self.cover_file = os.path.join(os.getcwd(), '.coverage') + self.cover_html_dir = os.path.join(os.getcwd(), 'cover') + if os.path.exists(self.cover_file): + os.unlink(self.cover_file) + if os.path.exists(self.cover_html_dir): + shutil.rmtree(self.cover_html_dir) + self.assertRaises(SystemExit, + super(TestCoverageMinPercentageTOTALPlugin, self).setUp) + + def runTest(self): + pass + if __name__ == '__main__': unittest.main() diff --git a/nose/plugins/cover.py b/nose/plugins/cover.py index f91e12a..378ebec 100644 --- a/nose/plugins/cover.py +++ b/nose/plugins/cover.py @@ -13,6 +13,7 @@ variable. import logging import re import sys +import StringIO from nose.plugins.base import Plugin from nose.util import src, tolist @@ -27,6 +28,7 @@ class Coverage(Plugin): coverPackages = None coverInstance = None coverErase = False + coverMinPercentage = None score = 200 status = {} @@ -51,6 +53,11 @@ class Coverage(Plugin): default=env.get('NOSE_COVER_TESTS'), help="Include test modules in coverage report " "[NOSE_COVER_TESTS]") + parser.add_option("--cover-min-percentage", action="store", + dest="cover_min_percentage", + default=env.get('NOSE_COVER_MIN_PERCENTAGE'), + help="Minimum percentage of coverage for tests" + "to pass [NOSE_COVER_MIN_PERCENTAGE]") parser.add_option("--cover-inclusive", action="store_true", dest="cover_inclusive", default=env.get('NOSE_COVER_INCLUSIVE'), @@ -119,6 +126,8 @@ class Coverage(Plugin): log.debug('Will put HTML coverage report in %s', self.coverHtmlDir) self.coverBranches = options.cover_branches self.coverXmlFile = None + if options.cover_min_percentage: + self.coverMinPercentage = int(options.cover_min_percentage.rstrip('%')) if options.cover_xml: self.coverXmlFile = options.cover_xml_file log.debug('Will put XML coverage report in %s', self.coverXmlFile) @@ -161,6 +170,22 @@ class Coverage(Plugin): log.debug("Generating XML coverage report") self.coverInstance.xml_report(modules, self.coverXmlFile) + # make sure we have minimum required coverage + if self.coverMinPercentage: + f = StringIO.StringIO() + self.coverInstance.report(modules, file=f) + m = re.search(r'-------\s\w+\s+\d+\s+\d+\s+(\d+)%\s+\d*\s{0,1}$', f.getvalue()) + if m: + percentage = int(m.groups()[0]) + if percentage < self.coverMinPercentage: + log.error('TOTAL Coverage did not reach minimum ' + 'required: %d%%' % self.coverMinPercentage) + sys.exit(1) + else: + log.error("No total percentage was found in coverage output, " + "something went wrong.") + + def wantModuleCoverage(self, name, module): if not hasattr(module, '__file__'): log.debug("no coverage of %s: no __file__", name) |