Django测试中如何设置仅测试生效的环境变量,无需逐个函数打补丁
解决方案
你之前的两种方案失效的原因分别是:
- 给
setUp方法单独打patch.dict装饰器时,补丁的作用域仅覆盖setUp方法执行周期,方法执行结束后补丁会自动回滚,因此测试方法运行时环境变量已经恢复为原值 - 直接在类外写patch语句没有生效,是因为没有正确将patch装饰器绑定到测试类的执行生命周期
方案1:手动管理环境变量生命周期(最稳妥)
直接在父类的setUp中保存原有环境变量值、写入新值,在tearDown中恢复原有值,所有继承该类的测试用例都会自动继承这个逻辑,不需要额外加装饰器:
import os from django.test import TestCase class TCommerceTestCase(TestCase): def setUp(self): # 保存原有环境变量值,不存在则存None self._original_inside_test = os.environ.get("INSIDE_TEST") # 设置目标环境变量 os.environ["INSIDE_TEST"] = "True" super().setUp() def tearDown(self): super().tearDown() # 恢复原有环境变量,避免影响其他测试 if self._original_inside_test is None: os.environ.pop("INSIDE_TEST", None) else: os.environ["INSIDE_TEST"] = self._original_inside_test def test_inside_test(self): # 此时可以正常拿到环境变量 self.assertEqual(os.environ["INSIDE_TEST"], "True") # 执行通过
方案2:将patch装饰器直接作用于测试类
把mock.patch.dict直接装饰在测试类上,补丁会作用于该类下所有的测试方法,包括setUp阶段:
import mock, os from django.test import TestCase @mock.patch.dict(os.environ, {"INSIDE_TEST": "True"}) class TCommerceTestCase(TestCase): def setUp(self): self.assertEqual(os.environ["INSIDE_TEST"], "True") # 执行通过 def test_inside_test(self): self.assertEqual(os.environ["INSIDE_TEST"], "True") # 执行通过
如果需要所有项目测试全局生效、不需要继承指定类,可以在测试启动入口(如manage.py的测试启动逻辑前、或者pytest的conftest.py的session级fixture中)直接设置对应环境变量即可。
内容的提问来源于stack exchange,提问作者Phil Brockman
相关产品推荐
相关产品推荐

