-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunittest_sorter.py
61 lines (48 loc) · 1.9 KB
/
unittest_sorter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import unittest
def suiteFactory(
*testcases,
testSorter = None,
suiteMaker = unittest.makeSuite,
newTestSuite = unittest.TestSuite):
"""
make a test suite from test cases, or generate test suites from test cases.
*testcases = TestCase subclasses to work on
testSorter = sort tests using this function over sorting by line number
suiteMaker = should quack like unittest.makeSuite.
newTestSuite = should quack like unittest.TestSuite.
"""
if testSorter is None:
ln = lambda f: getattr(tc, f).__code__.co_firstlineno
testSorter = lambda a, b: ln(a) - ln(b)
test_suite = newTestSuite()
for tc in testcases:
test_suite.addTest(suiteMaker(tc, sortUsing=testSorter))
return test_suite
def caseFactory(
scope = globals().copy(),
caseSorter = lambda f: __import__("inspect").findsource(f)[1],
caseSuperCls = unittest.TestCase,
caseMatches = __import__("re").compile("^Test")):
"""
get TestCase-y subclasses from frame "scope", filtering name and attribs
scope = iterable to use for a frame; preferably one with hashable
contents like a dictionary.
caseMatches = regex to match function names against; blank matches every
TestCase subclass
caseSuperCls = superclass of test cases; unittest.TestCase by default
caseSorter = sort test cases using this function over sorting by line
number
"""
from re import match
return sorted(
[
scope[obj] for obj in scope
if match(caseMatches, obj)
and issubclass(scope[obj], caseSuperCls)
],
key=caseSorter
)
def main(scope=globals().copy()):
cases = suiteFactory( *caseFactory(scope=scope) )
runner = unittest.TextTestRunner(verbosity=2)
runner.run(cases)