You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django单元测试:self属性修改在测试间持久化问题求助

字典修改在Django测试中跨用例残留的问题

从test_helpers文件导入包含默认数据的字典FORM_DATA,初始值为FORM_DATA['value_A'] = 0、FORM_DATA['value_B'] = 1000000。

无论将FORM_DATA赋值给self.form_data,还是在每个测试方法中赋值给变量,第二个测试都会保留第一个测试对字典的修改,不符合测试预期。添加打印语句调试后发现,即使在第二个测试的setUp()方法中,也显示着上一个测试修改后的值,每次新测试时self.form_data无法恢复为导入的默认数据。

测试代码

from test_helpers import FORM_DATA

class TestBaselineScenarios(TestCase):
    @classmethod
    def setUpClass(cls):
        super(TestBaselineScenarios, cls).setUpClass()
        long_running_data_setup()

    def setUp(self):
        self.form_data = FORM_DATA
        print("setUp", self.form_data['value_A'], self.form_data['value_B'])

    def test_one(self):
        print("1")
        print(self.form_data['value_A'], self.form_data['value_B'])
        self.form_data['value_A'] = 25000
        self.form_data['value_B'] = 700000
        print("2")
        print(self.form_data['value_A'], self.form_data['value_B'])
        simulation = test_helpers.create_simulation(form_data=self.form_data)
        simulation.run()
        self.assertEqual(0.8416667, round(simulation.success_rate(), 7))

    def test_two(self):
        print("3")
        print(self.form_data['value_A'], self.form_data['value_B'])
        self.form_data['value_A'] = 10000
        print("4")
        print(self.form_data['value_A'], self.form_data['value_B'])
        simulation = test_helpers.create_simulation(form_data=self.form_data)
        simulation.run()
        self.assertEqual(0.9916667, round(simulation.success_rate(), 7))

打印输出

setUp 0 1000000
1
0 1000000
2
25000 700000


setUp 25000 700000
3
25000 700000
4
10000 700000

问题原因

Python中字典是可变对象,导入的FORM_DATA是一个全局内存引用。当你执行self.form_data = FORM_DATA时,只是把这个全局引用赋值给了实例变量,并没有创建新的字典对象。测试方法中修改self.form_data的键值,实际上是直接修改了全局的FORM_DATA字典本身,所有测试用例共享同一个字典实例,因此修改会在测试间残留。

解决方法

1. 创建字典浅拷贝

在setUp中为self.form_data赋值字典的副本,避免直接操作全局对象:

def setUp(self):
    self.form_data = FORM_DATA.copy()  # 浅拷贝
    print("setUp", self.form_data['value_A'], self.form_data['value_B'])

如果FORM_DATA是嵌套字典(包含其他可变对象),需要使用深拷贝:

import copy

def setUp(self):
    self.form_data = copy.deepcopy(FORM_DATA)  # 深拷贝

2. 用函数返回新字典

修改test_helpers文件,定义一个返回新字典的函数,每次调用都会生成独立的字典实例:

# test_helpers.py
def get_form_data():
    return {'value_A': 0, 'value_B': 1000000}

在测试类中调用该函数获取初始数据:

from test_helpers import get_form_data

def setUp(self):
    self.form_data = get_form_data()

3. 在setUp中重新初始化

直接在setUp里手动初始化字典,完全脱离全局引用:

def setUp(self):
    self.form_data = {'value_A': 0, 'value_B': 1000000}

内容的提问来源于stack exchange,提问作者Lauren Boland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 15:48:46