将pytest测试彼此隔离

问题描述 投票:2回答:1

我正在开发一个快速发展的Python项目。最近,我们的测试套件开始有点难以管理。有些测试在它们所处的模块以错误的顺序执行时失败,尽管看起来很好。

我发现了一些其他问题,但是他们关心的是灯具:

Pytest fixtures interfering with each other

test isolation between pytest-hypothesis runs

虽然我们也在使用fixture,但我不认为问题在于它们,但更可能的是我们使用库,其中类具有内部状态,这些内部状态会被测试运行所改变,例如mockito-python

我最初来自Java世界,除非你明确地让你的测试依赖于彼此或做一些疯狂和不寻常的事情,否则这种情况不会发生。遵循Python中的相同做法导致我遇到这些问题,因此我意识到我可能会遗漏一些Python测试开发的关键规则。

有可能告诉pytest在各种模块运行之间删除/恢复/重新初始化所有类的内部状态吗?

如果没有,我们应该在测试开发过程中遵循哪些规则来防止这些问题?

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

python unit-testing testing pytest fixtures
1个回答
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

结果,测试的执行顺序在测试执行之间发生了变化。如果错误地将您的测试碰巧具有依赖性,那么您可能能够以这种方式弄清楚,因为某些执行命令会导致失败。当然,你会从一个小规模开始(只执行少量的测试),所以你有机会更容易找到罪魁祸首。

也许值得一试......

© www.soinside.com 2019 - 2024. All rights reserved.