例如,我希望它们按照它们在文件中出现的顺序运行。
import unittest
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_de_last_ding(self): pass
if __name__ == "__main__":
unittest.main(verbosity=2)
运行这个给
test_after_first (__main__.Test_AnotherClass) ... ok
test_de_last_ding (__main__.Test_AnotherClass) ... ok
test_first (__main__.Test_AnotherClass) ... ok
test_2nd_run_me (__main__.Test_MyTests) ... ok
test_and_me_last (__main__.Test_MyTests) ... ok
test_run_me_first (__main__.Test_MyTests) ... ok
不是我想要的
我在搜索所有跳舞并通过调用/分组测试或说出这些问题后在SO上找到的答案
“不要这样做,只是用不同的方式编写测试”或
“按字典顺序命名测试!”
...除了一个,它可以满足我的要求:
loader = unittest.TestLoader()
ln = lambda f: getattr(MyTestCase, f).im_func.func_code.co_firstlineno
lncmp = lambda a, b: cmp(ln(a), ln(b))
loader.sortTestMethodsUsing = lncmp
unittest.main(testLoader=loader, verbosity=2)
但仅适用于一个TestCase类,并且仅适用于Python 2。
我想运行所有的Python 3unittest.TestCase
子类,并且希望能够指定用于排序的确切算法。
我可以在里面做unittest
吗?
做了之后很多的研究,由SO和Python的大大的资助,help
而不是在所有的单元测试的文档,我得到的答案我最初想,所以我想我会写这篇文章,以帮助别人,因为这是一个公平的(但显然通用) 要求。
要运行特定的测试用例,我们需要TestSuite
为该TestCase新建一个。让我们对任意数量的TestCases进行以下操作:
def suiteFactory(*testcases):
ln = lambda f: getattr(tc, f).__code__.co_firstlineno
lncmp = lambda a, b: ln(a) - ln(b)
test_suite = unittest.TestSuite()
for tc in testcases:
test_suite.addTest(unittest.makeSuite(tc, sortUsing=lncmp))
return test_suite
非常简单:
定义函数以获取函数的行号。在Python 3中,我们将属性从更改func.im_func.func_code.co_firstlineno
为func.__code__.co_firstlineno
,您可以使用查看dir(anyFunction)
。
定义一个函数,以根据两个参数cmp
的行号对它们进行排序。cmp
出于“人们可以做数学”的考虑,Python 3中没有使用它,因此出于可读性的考虑,我所做的正是它所做的。
制作一个new
空白TestSuite()
,并给它一个TestCase或十个,然后告诉它使用第二点对TestCase的方法进行排序:cmp
输入它们的行号。
现在我们需要对文件的TestCase子类进行排序。
为此,我们可以查看globals()
和及其属性。
def caseFactory():
from inspect import findsource
g = globals().copy()
cases = [
g[obj] for obj in g
if obj.startswith("Test")
and issubclass(g[obj], unittest.TestCase)
]
ordered_cases = sorted(cases, key=lambda f: findsource(f)[1])
return ordered_cases
这只会得到unittest.TestCase
以Test
或任何您喜欢的命名约定开头的所有子类,然后按行号对它们进行排序:findsource(object)
返回源代码,并将行号作为索引1,这是我们关心的。
要将其包装成某种东西,我们可以使用:
if __name__ == "__main__":
cases = suiteFactory(*caseFactory())
runner = unittest.TextTestRunner(verbosity=2)
runner.run(cases)
这确实分隔了输出,但是如果最低级别的测试位于文件的顶部(或底部,或某处),并且应该在更高级别的测试之前运行,则可能是一件好事。
因此,完整的输出为:
test_run_me_first (__main__.Test_MyTests) ... ok
test_2nd_run_me (__main__.Test_MyTests) ... ok
test_and_me_last (__main__.Test_MyTests) ... ok
test_first (__main__.Test_AnotherClass) ... ok
test_after_first (__main__.Test_AnotherClass) ... ok
test_de_last_ding (__main__.Test_AnotherClass) ... ok
----------------------------------------------------------------------
Ran 6 tests in 0.000s
OK
成功!
您可以在Github gist上找到更有趣的版本。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句