summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrien Di Mascio <Adrien.DiMascio@logilab.fr>2007-04-04 10:41:09 +0200
committerAdrien Di Mascio <Adrien.DiMascio@logilab.fr>2007-04-04 10:41:09 +0200
commita4f3ff6982ab963f265d1259e800ea23366110a7 (patch)
tree1594428d3243170be847678269816ef216e88a37
parentac8abd865c5c32d7f854cc45df4fb657f59f3617 (diff)
downloadlogilab-common-a4f3ff6982ab963f265d1259e800ea23366110a7.tar.gz
pytest can skip tests
-rw-r--r--pytest.py9
-rw-r--r--test/unittest_testlib.py32
-rw-r--r--testlib.py41
3 files changed, 79 insertions, 3 deletions
diff --git a/pytest.py b/pytest.py
index a6d348e..6df927c 100644
--- a/pytest.py
+++ b/pytest.py
@@ -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"""
diff --git a/testlib.py b/testlib.py
index 8586cae..9c5e4c3 100644
--- a/testlib.py
+++ b/testlib.py
@@ -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: