我正在检查 Django 的设置模块是如何构建的以及 override_settings 是如何构建的装饰器在测试时处理设置,我只是看不到 implementation 如何处理这个装饰器避免在并行运行测试时出现问题。
我在 enable
中看到它它分配给设置的方法'_wrapped
将设置值与应用的更改相关联,并存储先前值的副本,然后在 disable
中恢复方法。在按顺序执行时,这对我来说没问题。但是当并行运行测试时,我无法在不影响也使用装饰器的其他测试的情况下看到它是如何工作的,假设覆盖相同的值。我看到的是,访问 settings.OVERRIDDEN_SETTING 时,将在各处返回最新执行的测试设置的值。事实上,这个设置重写也应该影响其他测试中返回的值,即使它们没有被装饰。
我的意思是,如果我们有这两个测试:
@override_settings(SETTING=1):
def test_1(self):
...
...
print(settings.SETTING)
@override_settings(SETTING=2):
def test_2(self):
...
...
print(settings.SETTING)
def test_3(self):
...
...
print(settings.SETTING)
如果它们并行运行,假设 test_1
被执行,开始执行它的代码,同时 test_2
在 print
之前调用test_1
中的声明已经执行,通过检查装饰器实现,我希望它们都打印 2
由于他们的 print
.并且取决于它何时被执行,test_3
如果它也并行运行,将返回原始值 1 或 2。
肯定有一些我没有考虑到的东西,因为我不认为这段代码在经过这么多时间后容易出现这种竞争情况。
如果能帮助理解这一点,我们将不胜感激。
最佳答案
并行测试在单独的进程中运行,每个进程访问其自己的设置
副本。
因此,Django的override_settings
不需要专门处理并行测试。
我们可以根据经验验证不安全的直接修改而不是 override_settings
(注意 sleep
以确保 test_3
在 test_1 之后运行
和 test_2
修改值):
from time import sleep
from django.conf import settings
from django.test import TestCase
class TestOverrideSettings1(TestCase):
# @override_settings(SETTING=1)
def test_1(self):
settings.SETTING = 1
print(settings.SETTING)
class TestOverrideSettings2(TestCase):
# @override_settings(SETTING=2)
def test_2(self):
settings.SETTING = 2
print(settings.SETTING)
class TestOverrideSettings3(TestCase):
def test_3(self):
sleep(1)
print(settings.SETTING)
运行测试:
$ python manage.py test
1
.2
.2
.
并行运行测试:
$ python manage.py test --parallel
1
2
..0
.
关于django - Django 的 "override_settings"装饰器在并行启动测试时如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67295624/