如何在PyTest的两次测试之间重置全局变量?
解决全局变量在测试间重置的问题
问题原因
你的测试失败是因为main.py里的全局变量y,第一次调用inc(3)后变成了1,第二次调用时又累加为2,导致返回值是3+2+1=6,和断言的5不符。核心问题就是两次测试之间全局变量的状态没被重置。
三种解决办法
1. 用pytest自动重置全局变量
如果用pytest跑测试,写个自动生效的fixture,每个测试前后重置y:
修改test_main.py:
import pytest from main import inc import main @pytest.fixture(autouse=True) def reset_y(): # 先存好初始值,测试完再改回去 original_y = main.y yield main.y = original_y def test_answer(): assert inc(3) == 5 def test_answer_again(): assert inc(3) == 5
autouse=True会让这个fixture自动作用于所有测试,不用手动调用。
2. 每个测试前手动重置
不想用fixture的话,直接在每个测试开头把y改回0:
from main import inc import main def test_answer(): main.y = 0 assert inc(3) == 5 def test_answer_again(): main.y = 0 assert inc(3) == 5
这里要注意必须导入整个main模块,不能单独from main import y,因为单独导入的是变量的副本,改了不会影响模块里的全局变量。
3. 重构代码,彻底去掉全局变量(推荐)
全局变量的副作用本来就容易出问题,最好的方式是把状态封装起来,比如用类:
修改main.py:
class Counter: def __init__(self): self.y = 0 def inc(self, x): self.y += 1 return x + self.y + 1
测试的时候每个用例新建一个Counter实例,状态完全隔离:
from main import Counter def test_answer(): counter = Counter() assert counter.inc(3) == 5 def test_answer_again(): counter = Counter() assert counter.inc(3) == 5
这种方式从根源上解决了全局状态的问题,代码也更易维护。
内容的提问来源于stack exchange,提问作者poiuytrez
相关产品推荐
相关产品推荐

