【问题标题】:How Django's "override_settings" decorator works when launching tests in parallel并行启动测试时 Django 的“override_settings”装饰器如何工作
【发布时间】:2021-07-21 12:54:50
【问题描述】:

我正在检查 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_1 中的print 语句执行之前调用test_2,通过检查装饰器实施时,我希望他们都打印2 作为他们print 的结果。并且根据执行的时间,test_3 将返回原始值 1,如果它也并行运行,则返回 2。

一定有一些我没有考虑到的东西,因为我认为这段代码在经过这么长时间之后不会容易出现这种竞争条件。

任何帮助理解这一点将不胜感激。

【问题讨论】:

    标签: django django-testing


    【解决方案1】:

    并行测试在单独的进程中运行,每个进程都访问自己的settings副本。

    因此,Django 的override_settings 不需要专门处理并行测试。

    我们可以凭经验验证不安全的直接修改而不是override_settings(注意sleep以确保test_3test_1test_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
    .
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 2015-05-29
      • 2012-08-23
      • 2017-05-20
      • 2017-08-20
      • 2021-02-13
      • 2018-05-30
      相关资源
      最近更新 更多