Python unittest.TestCase 执行顺序
在Python的unittest
中,有没有办法设置测试用例的执行顺序呢?
在我现在的TestCase
类里,有些测试用例会产生一些影响,这些影响会影响到其他测试用例的正常运行。现在我意识到,正确的做法是使用setUp()
来处理所有的准备工作,但我想实现一种设计,让每个后续的测试都能稍微增加一些状态,以便下一个测试可以使用。我觉得这样更优雅。
class MyTest(TestCase):
def test_setup(self):
# Do something
def test_thing(self):
# Do something that depends on test_setup()
理想情况下,我希望测试按照它们在类中出现的顺序来运行。但似乎它们是按照字母顺序来执行的。
11 个回答
来自 unittest — 单元测试框架,部分 组织测试代码:
注意:各种测试的执行顺序是通过对测试方法名称进行排序来决定的,这个排序是基于字符串的内置顺序。
所以你只需要确保 test_setup
的名字是所有测试方法中字符串值最小的。
请注意,你不应该依赖这种行为——不同的测试函数应该是独立的,执行顺序不应该影响它们的结果。 如果你确实需要特定的执行顺序,可以参考上面 ngcohlan的回答。
对于这样的期望,写一个整体的测试是个好习惯。不过,如果你像我一样有点搞笑的话,你可以简单地把方法按字母顺序写得不好看,这样它们就会按照从a到b的顺序排列,正如Python文档中提到的 - unittest — 单元测试框架
请注意,各个测试用例的运行顺序是通过对测试函数名称进行排序来决定的,这个排序是基于字符串的内置顺序。
示例
def test_a_first():
print "1"
def test_b_next():
print "2"
def test_c_last():
print "3"
不要把它们当成独立的测试——如果你想要一个整体的测试,就写一个整体的测试。
class Monolithic(TestCase):
def step1(self):
...
def step2(self):
...
def _steps(self):
for name in dir(self): # dir() result is implicitly sorted
if name.startswith("step"):
yield name, getattr(self, name)
def test_steps(self):
for name, step in self._steps():
try:
step()
except Exception as e:
self.fail("{} failed ({}: {})".format(step, type(e), e))
如果测试之后出现失败,并且你想知道所有失败的步骤,而不是在第一个失败的步骤就停止测试,你可以使用 subtests
功能:https://docs.python.org/3/library/unittest.html#distinguishing-test-iterations-using-subtests
(对于 Python 3.4 之前的版本,可以通过 unittest2
使用 subtest 功能:https://pypi.python.org/pypi/unittest2)