-
-
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
caseFactorydiffers fromcaseFactory's own module (test_4for 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.pyAnd then I try to import thesefunctions to my second file where I running my tests:
test_3.pyThe problem is that when I try to run my
test_3.pyfile I can't get any result.