在pytest测试中如何安全定义并复用共享测试对象?
pytest中复用测试字典的最佳实践
针对你在测试中重复定义字典、担心全局字典被修改污染的问题,以下是几种实用的解决方案,按推荐优先级排序:
1. 使用pytest Fixture(最推荐)
Fixture是pytest的核心特性,默认每个测试函数都会生成全新的实例,天然隔离测试间的修改,完全解决污染问题。
import pytest @pytest.fixture def test_dict(): # 在这里定义基础字典,每个测试调用时都会返回新的对象 return { "key1": "value1", "key2": 2, "key3": ["a", "b"] } # 测试函数直接注入fixture即可使用 def test_foo_modify_key(test_dict): test_dict["key1"] = "modified_value" assert foo(test_dict) == "modified_result" def test_foo_original_state(test_dict): # 这里的test_dict是全新的,不受上一个测试的修改影响 assert test_dict["key1"] == "value1" assert foo(test_dict) == "original_result"
如果需要在多个测试模块复用这个fixture,可以把它放到conftest.py文件中,无需导入就能在所有测试函数里使用。
2. 定义工厂函数
如果需要灵活生成带自定义参数的字典,工厂函数是不错的选择——每次调用都会返回新的字典实例,同时支持按需修改初始值。
def create_test_dict(custom_updates=None): base_dict = { "key1": "value1", "key2": 2, "key3": ["a", "b"] } if custom_updates: base_dict.update(custom_updates) return base_dict def test_foo_with_custom_key(): test_dict = create_test_dict({"key2": 100}) assert foo(test_dict) == "custom_result" def test_foo_default(): test_dict = create_test_dict() assert foo(test_dict) == "default_result"
3. 全局字典 + 深拷贝(备选方案)
如果一定要用全局变量存储基础字典,每次测试前通过深拷贝生成新实例,避免修改原全局对象。注意必须用deepcopy,因为字典中的可变对象(比如列表、嵌套字典)用浅拷贝会共享引用,依然会污染原数据。
import copy # 全局存储基础模板,只做读取不直接修改 _BASE_TEST_DICT = { "key1": "value1", "key2": 2, "key3": ["a", "b"] } def test_foo_modify_nested(): test_dict = copy.deepcopy(_BASE_TEST_DICT) test_dict["key3"].append("c") assert foo(test_dict) == "nested_modified_result" def test_foo_original_nested(): test_dict = copy.deepcopy(_BASE_TEST_DICT) # 这里的key3还是初始的["a", "b"] assert test_dict["key3"] == ["a", "b"]
内容的提问来源于stack exchange,提问作者Álvaro A. Gutiérrez-Vargas
相关产品推荐
相关产品推荐

