-
-
Save catb0t/304ececa6c55f6e3788d to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3 | |
import unittest | |
import inspect | |
import re | |
class Test_MyTests(unittest.TestCase): | |
def test_run_me_first(self): pass | |
def test_2nd_run_me(self): pass | |
def test_and_me_last(self): pass | |
class Test_AnotherClass(unittest.TestCase): | |
def test_first(self): pass | |
def test_after_first(self): pass | |
def test_the_real_final_thing(self): pass | |
def _sourceFinder (f): | |
return inspect.findsource(f)[1] | |
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 tc, f: getattr(tc, f).__code__.co_firstlineno | |
testSorter = lambda tc, a, b: ln(tc, a) - ln(tc, b) | |
test_suite = newTestSuite() | |
for tc in testcases: | |
test_suite.addTest( | |
suiteMaker( | |
tc, | |
sortUsing=lambda a, b, case=tc: testSorter(case, a, b) | |
) | |
) | |
return test_suite | |
def caseFactory ( | |
scope = globals().copy(), | |
caseSorter = _sourceFinder, | |
caseSuperCls = unittest.TestCase, | |
caseMatches = re.compile("^Test") ): | |
""" | |
get TestCase-y subclasses from frame "scope", filtering name and attribs | |
scope = iterable to use for a frame; preferably a hashable (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 | |
""" | |
# note that 'name' is the string key of the object in the dictionary | |
return sorted( | |
[ | |
scope[name] | |
for name in scope | |
if re.match(caseMatches, name) and inspect.isclass(scope[name]) | |
and issubclass( | |
scope[name], | |
caseSuperCls | |
) | |
], | |
key=caseSorter | |
) | |
if __name__ == '__main__': | |
cases = suiteFactory(*caseFactory()) | |
runner = unittest.TextTestRunner(verbosity=2) | |
runner.run(cases) |
@dron4ik86 There was a bizarre bug in the code that I fixed.
However, when the calling module of caseFactory
differs from caseFactory
's own module (test_4
for you), you have to give the keyword argument scope=globals().copy()
.
caseFactory
's default for that argument is its own enclosing global scope, which is its module.
The correct version of your code looks like
#! /usr/bin/env python3
import unittest
from test_4 import suiteFactory, caseFactory
class Test_MyTests(unittest.TestCase):
def test_run_me_first(self):
print("1")
def test_2nd_run_me(self):
print("2")
def test_and_me_last(self):
print("3")
if __name__ == '__main__':
cases = suiteFactory(*caseFactory( scope=globals().copy() ))
runner = unittest.TextTestRunner(verbosity=2)
runner.run(cases)
and works properly.
@dron4ik86 There was a bizarre bug in the code that I fixed.
However, when the calling module of
caseFactory
differs fromcaseFactory
's own module (test_4
for you), you have to give the keyword argumentscope=globals().copy()
.
caseFactory
's default for that argument is its own enclosing global scope, which is its module.The correct version of your code looks like
#! /usr/bin/env python3 import unittest from test_4 import suiteFactory, caseFactory class Test_MyTests(unittest.TestCase): def test_run_me_first(self): print("1") def test_2nd_run_me(self): print("2") def test_and_me_last(self): print("3") if __name__ == '__main__': cases = suiteFactory(*caseFactory( scope=globals().copy() )) runner = unittest.TextTestRunner(verbosity=2) runner.run(cases)and works properly.
Thank you for your answer
I fixed a bug where non-class variables matching the regex in the scope were picked up by the iterator and produced an error on issubclass.
Hi, I try to take the function suiteFactory and caseFactory to another file something like this
test_4.py
And then I try to import thesefunctions to my second file where I running my tests:
test_3.py
The problem is that when I try to run my
test_3.py
file I can't get any result.