pytest中共享字典变量在测试间被修改,如何实现测试用例独立?
解决测试用例共享可变数据导致的依赖问题
问题根源很直接:Python里字典是可变对象,from data import a导入的是同一个字典引用。test_1修改了a['data']的内容后,test_2读取的是已经被修改后的状态,所以单独跑test_2没问题,同时跑两个就会失败。
下面是几种可行的解决方案,按推荐程度排序:
1. 用pytest Fixture(测试场景最优)
借助pytest的fixture特性,为每个测试用例生成独立的数据源。fixture默认是函数级别的,每个测试执行前都会重新生成数据,天然保证隔离:
# test_mytest.py import pytest @pytest.fixture def test_data(): # 每个测试用例都会拿到新的字典实例 return {'data1': 'mydata', 'data2': 'mydata2'} def test_1(test_data): test_data['data1'] = 'new data' def test_2(test_data): assert test_data['data1'] == 'mydata'
如果要保留原data.py的结构,也可以在fixture里封装原始数据的获取:
# test_mytest.py from data import a import pytest import copy @pytest.fixture def test_data(): # 深拷贝原始数据,避免修改原对象 return copy.deepcopy(a['data']) def test_1(test_data): test_data['data1'] = 'new data' def test_2(test_data): assert test_data['data1'] == 'mydata'
2. 用工厂函数生成新实例
修改data.py,把数据定义成函数,每次调用都返回新的字典,从根源避免共享引用:
# data.py def get_test_data(): return { "data": { 'data1': 'mydata', 'data2': 'mydata2' } }
测试文件里每次调用函数获取独立数据:
# test_mytest.py from data import get_test_data import pytest def test_1(): test_data = get_test_data()['data'] test_data['data1'] = 'new data' def test_2(): test_data = get_test_data()['data'] assert test_data['data1'] == 'mydata'
这种方式不仅适合测试,也能在其他业务代码中复用,通用性强。
3. 手动深拷贝原始数据
如果不想修改data.py,可以在每个测试用例里对原始数据做深拷贝,确保操作的是独立副本:
# test_mytest.py from data import a import pytest import copy def test_1(): test_data = copy.deepcopy(a['data']) test_data['data1'] = 'new data' def test_2(): test_data = copy.deepcopy(a['data']) assert test_data['data1'] == 'mydata'
这种方式需要每个测试都手动处理,不够简洁,适合临时快速修复。
内容的提问来源于stack exchange,提问作者Manish Saini
相关产品推荐
相关产品推荐

