相互隔离pytest测试

时间:2019-03-08 16:41:15

标签: python unit-testing testing pytest fixtures

我正在研究一个快速发展的Python项目。最近,我们的测试套件开始变得有些难以管理。尽管测试模块似乎隔离良好,但当它们以错误的顺序执行时,某些测试会失败。

我发现了与此有关的其他问题,但他们与灯具有关:

Pytest fixtures interfering with each other

test isolation between pytest-hypothesis runs

虽然我们也使用固定装置,但我认为问题不在于它们,而是更有可能是因为我们使用的库中,类的内部状态会因测试运行而改变,例如{{ 1}}。

我最初来自Java世界,除非您明确地使您的测试相互依赖,或者做一些疯狂和不寻常的事情,否则这不会发生。遵循相同的Python做法集导致了这些问题,所以我意识到我可能缺少Python测试开发的一些关键规则。

是否可以告诉mockito-python删除/还原/重新初始化各个模块运行之间所有类的内部状态?

否则,在测试开发过程中应遵循哪些规则来防止这些问题?

编辑:我们发现的问题之一是,我们在测试文件的顶层设置了一些对象,这些对象是由pytest创建的。执行测试时,首先将文件全部导入,然后执行测试。发生的事情是,有一个测试正在调用mockito-python,该操作将拆除嘲讽的模拟注册表中的所有模拟。因此,当实际执行测试时,另一个测试已经拆除了其模拟。这种行为是违反直觉的,特别是对于没有经验的开发人员。

1 个答案:

答案 0 :(得分:2)

在python中,某些状态被错误地修改很容易发生。例如,在将列表分配给变量时,很容易忘记要创建列表的副本时添加[:]

x = [0,1,2,3,4,5]
y = x    # oops, should have been x[:]
y[2] = 7 # now we modify state somewhere...
x
=> [0, 1, 7, 3, 4, 5]

至少有可能识别此类问题的一种可能方法是以随机顺序执行单元测试。我根据https://stackoverflow.com/a/4006044/5747415的想法进行了实验:

import unittest
import random
def randcmp(_, x, y):
    return random.randrange(-1, 2)
unittest.TestLoader.sortTestMethodsUsing = randcmp

结果,测试的执行顺序在测试执行之间改变。如果错误地使您的测试碰巧具有依赖性,则您可以通过这种方式找出原因,因为某些执行命令会导致失败。当然,您会从小规模开始(仅执行少量测试),因此有机会更轻松地找到罪魁祸首。

也许值得尝试...