diff options
author | Adrien Di Mascio <Adrien.DiMascio@logilab.fr> | 2007-04-04 10:41:09 +0200 |
---|---|---|
committer | Adrien Di Mascio <Adrien.DiMascio@logilab.fr> | 2007-04-04 10:41:09 +0200 |
commit | a4f3ff6982ab963f265d1259e800ea23366110a7 (patch) | |
tree | 1594428d3243170be847678269816ef216e88a37 | |
parent | ac8abd865c5c32d7f854cc45df4fb657f59f3617 (diff) | |
download | logilab-common-a4f3ff6982ab963f265d1259e800ea23366110a7.tar.gz |
pytest can skip tests
-rw-r--r-- | pytest.py | 9 | ||||
-rw-r--r-- | test/unittest_testlib.py | 32 | ||||
-rw-r--r-- | testlib.py | 41 |
3 files changed, 79 insertions, 3 deletions
@@ -185,6 +185,13 @@ def parseargs(): action="store", dest="printonly", default=None, help="Only prints lines matching specified pattern (implies capture) " "(only make sense when pytest run one test file)") + parser.add_option('-s', '--skip', + # XXX: I wish I could use the callback action but it + # doesn't seem to be able to get the value + # associated to the option + action="store", dest="skipped", default=None, + help="test names matching this name will be skipped " + "to skip several patterns, use commas") parser.add_option('-q', '--quiet', callback=rebuild_cmdline, action="callback", help="Minimal output") @@ -202,6 +209,8 @@ def parseargs(): testlib.ENABLE_DBC = options.dbc if options.printonly: newargs.extend(['--printonly', options.printonly]) + if options.skipped: + newargs.extend(['--skip', options.skipped]) # append additional args to the new sys.argv and let unittest_main # do the rest newargs += args diff --git a/test/unittest_testlib.py b/test/unittest_testlib.py index 3174689..9e77684 100644 --- a/test/unittest_testlib.py +++ b/test/unittest_testlib.py @@ -341,7 +341,39 @@ class TestLoaderTC(TestCase): collected = self.loader.loadTestsFromName(pattern, MyMod) yield self.assertEquals, len(collected), expected_count + def test_collect_everything_and_skipped_patterns(self): + testdata = [ (['foo1'], 3), (['foo'], 2), + (['foo', 'bar'], 0), + ] + for skipped, expected_count in testdata: + self.loader.skipped_patterns = skipped + testsuite = self.loader.loadTestsFromModule(self.module) + yield self.assertEquals, testsuite.countTestCases(), expected_count + + + def test_collect_specific_pattern_and_skip_some(self): + testdata = [ ('bar', ['foo1'], 2), ('bar', [], 2), + ('bar', ['bar'], 0), ] + + for runpattern, skipped, expected_count in testdata: + self.loader.skipped_patterns = skipped + collected = self.loader.loadTestsFromName(runpattern, self.module) + yield self.assertEquals, len(collected), expected_count + def test_skip_classname(self): + testdata = [ (['BarTC'], 3), (['FooTC'], 1), ] + for skipped, expected_count in testdata: + self.loader.skipped_patterns = skipped + testsuite = self.loader.loadTestsFromModule(self.module) + yield self.assertEquals, testsuite.countTestCases(), expected_count + + def test_skip_classname_and_specific_collect(self): + testdata = [ ('bar', ['BarTC'], 1), ('foo', ['FooTC'], 0), ] + for runpattern, skipped, expected_count in testdata: + self.loader.skipped_patterns = skipped + collected = self.loader.loadTestsFromName(runpattern, self.module) + yield self.assertEquals, len(collected), expected_count + def bootstrap_print(msg, output=sys.stdout): """sys.stdout will be evaluated at function parsing time""" @@ -431,6 +431,11 @@ class NonStrictTestLoader(unittest.TestLoader): python test_foo.py test_foo1 will run test_foo1 python test_foo.py test_bar will run FooTC.test_bar1 and BarTC.test_bar2 """ + + def __init__(self): + self.skipped_patterns = [] + + def loadTestsFromNames(self, names, module=None): suites = [] for name in names: @@ -445,12 +450,18 @@ class NonStrictTestLoader(unittest.TestLoader): issubclass(obj, unittest.TestCase): classname = obj.__name__ methodnames = [] + if self._this_is_skipped(classname): + continue # obj is a TestCase class for attrname in dir(obj): if attrname.startswith(self.testMethodPrefix): attr = getattr(obj, attrname) if callable(attr): - methodnames.append(attrname) + for pattern in self.skipped_patterns: + if pattern in attrname: + break + else: + methodnames.append(attrname) # keep track of class (obj) for convenience tests[classname] = (obj, methodnames) return tests @@ -514,6 +525,23 @@ class NonStrictTestLoader(unittest.TestLoader): """ return pattern in methodname + + def _this_is_skipped(self, testedname): + for pattern in self.skipped_patterns: + if pattern in testedname: + return True + return False + + def getTestCaseNames(self, testCaseClass): + """Return a sorted sequence of method names found within testCaseClass + """ + if self._this_is_skipped(testCaseClass.__name__): + return [] + testnames = super(NonStrictTestLoader, self).getTestCaseNames(testCaseClass) + return [testname for testname in testnames + if not self._this_is_skipped(testname)] + + class SkipAwareTestProgram(unittest.TestProgram): # XXX: don't try to stay close to unittest.py, use optparse USAGE = """\ @@ -526,6 +554,7 @@ Options: -x, --exitfirst Exit on first failure -c, --capture Captures and prints standard out/err only on errors -p, --printonly Only prints lines matching specified pattern (implies capture) + -s, --skip skip test matching this pattern (no regexp for now) -q, --quiet Minimal output Examples: @@ -547,10 +576,13 @@ Examples: self.exitfirst = False self.capture = 0 self.printonly = None + skipped_patterns = [] import getopt try: - options, args = getopt.getopt(argv[1:], 'hHvixqcp:', - ['help','verbose','quiet', 'pdb', 'exitfirst', 'capture', 'printonly=']) + options, args = getopt.getopt(argv[1:], 'hHvixqcp:s:', + ['help','verbose','quiet', 'pdb', + 'exitfirst', 'capture', 'printonly=', + 'skip=']) for opt, value in options: if opt in ('-h','-H','--help'): self.usageExit() @@ -566,6 +598,9 @@ Examples: self.capture += 1 if opt in ('-p', '--printonly'): self.printonly = re.compile(value) + if opt in ('-s', '--skip'): + skipped_patterns = [pat.strip() for pat in value.split(',')] + self.testLoader.skipped_patterns = skipped_patterns if self.printonly is not None: self.capture += 1 if len(args) == 0 and self.defaultTest is None: |