【问题标题】:Unit Testing with django-pipeline使用 django-pipeline 进行单元测试
【发布时间】:2012-10-10 10:13:14
【问题描述】:

我在使用 django-pipeline 的应用程序的单元测试视图中遇到问题?每当我在任何 URL 上执行 client.get() 时,都会产生以下异常:

ValueError:找不到文件“css/bootstrap.css”,

它是bootstrap.css当然不重要,但是由于这个异常我无法执行视图渲染。

欢迎任何指南/提示!

【问题讨论】:

  • DEBUG 设置为 True 还是 False ?
  • 你可以直接测试视图而不是使用 django 测试客户端吗?也许使用模拟来检查模板渲染+上下文?
  • Jonas,DEBUG 设置为 True,应该绕过管道操作。 (不过我会仔细检查一下。)谢谢!
  • Hwjp,因为我放弃了尝试找出解决方案,我最终让视图未经测试,并简单地测试其他类。
  • 默认的 Django 测试运行器将 DEBUG 设置为 False,无论您的设置文件中有什么:无论配置文件中的 DEBUG 设置的值如何,所有 Django 测试都以 DEBUG=False 运行。这是为了确保观察到的代码输出与生产环境中的输出相匹配。

标签: django django-testing


【解决方案1】:

我遇到了类似的问题。但是,设置

STATICFILES_STORAGE='pipeline.storage.NonPackagingPipelineStorage'

在运行测试时仅部分解决了我的问题。如果您想运行 LiverServerTestCase 测试而不必在运行测试之前调用“collecstatic”,我还必须完全禁用管道:

PIPELINE_ENABLED=False

从 django 1.4 开始,修改测试设置相当容易 - 有一个方便的装饰器适用于方法或 TestCase 类:

https://docs.djangoproject.com/en/1.6/topics/testing/tools/#overriding-settings

例如

from django.test.utils import override_settings

@override_settings(STATICFILES_STORAGE='pipeline.storage.NonPackagingPipelineStorage', PIPELINE_ENABLED=False)
class BaseTestCase(LiveServerTestCase):
    """
    A base test case for Selenium
    """

    def setUp(self):
        ...

然而,正如@jrothenbuhler 在他的回答中所描述的那样,这会产生不一致的结果。无论如何,如果您正在运行集成测试,这并不理想——您应该尽可能地模拟生产以发现任何潜在问题。似乎 django 1.7 以新的测试用例“StaticLiveServerTestCase”的形式为此提供了解决方案。从文档: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#django.contrib.staticfiles.testing.StaticLiveServerCase

这个 unittest TestCase 子类扩展 django.test.LiveServerTestCase.

就像它的父级一样,您可以使用它来编写涉及 运行被测代码并使用测试工具使用它 通过 HTTP(例如 Selenium、PhantomJS 等),因为它是 需要同时发布静态资产。

我没有对此进行测试,但听起来很有希望。现在我正在使用自定义测试运行器在他的解决方案中执行@jrothenbuhler 的操作,这不需要您运行 collectstatic。如果您真的非常希望它运行 collectstatic,您可以执行以下操作:

from django.conf import settings
from django.test.simple import DjangoTestSuiteRunner
from django.core.management import call_command

class CustomTestRunner(DjangoTestSuiteRunner):
    """
    Custom test runner to get around pipeline and static file issues
    """

    def setup_test_environment(self):
        super(CustomTestRunner, self).setup_test_environment()
        settings.STATICFILES_STORAGE = 'pipeline.storage.NonPackagingPipelineStorage'
        call_command('collectstatic', interactive=False)

在settings.py中

TEST_RUNNER = 'path.to.CustomTestRunner'

【讨论】:

    【解决方案2】:

    我也遇到了同样的问题。我使用自定义测试运行器解决了这个问题:

    from django.conf import settings
    from django.test.simple import DjangoTestSuiteRunner
    
    from pipeline.conf import settings as pipeline_settings
    
    class PipelineOverrideRunner(DjangoTestSuiteRunner):
    
        def setup_test_environment(self):
            '''Override STATICFILES_STORAGE and pipeline DEBUG.'''
            super(PipelineOverrideRunner, self).setup_test_environment()
            settings.STATICFILES_STORAGE = 'pipeline.storage.PipelineFinderStorage'
            pipeline_settings.DEBUG = True
    

    然后在你的 settings.py 中:

    TEST_RUNNER = 'path.to.PipelineOverrideRunner'
    

    将管道的 DEBUG 设置设置为 True 可确保不会打包静态文件。这避免了在运行测试之前运行 collectstatic 的需要。请注意,它是管道的 DEBUG 设置,而不是 Django 的设置,它在此处被覆盖。这样做的原因是您希望 Django 的 DEBUG 在测试时为 False 以最好地模拟生产环境。

    将 STATICFILES_STORAGE 设置为 PipelineFinderStorage 可以在 Django 的 DEBUG 设置为 False 时找到静态文件,就像在运行测试时一样。

    我决定在自定义测试运行程序而不是自定义 TestCase 中覆盖这些设置的原因是因为某些东西,例如 django.contrib.staticfiles.storage.staticfiles_storage 对象,基于这些和其他设置一次设置。在使用自定义 TestCase 时,我遇到了测试通过和失败不一致的问题,具体取决于加载 django.contrib.staticfiles.storage 等模块时覆盖是否生效。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。我在测试时通过使用不同的STATIC_FILES_STORAGE 设法绕过它:

      STATICFILES_STORAGE = 'pipeline.storage.NonPackagingPipelineStorage'
      

      我有单独的生产和测试设置文件,所以我只是把它放在我的测试版本中,但如果你不这样做,你可以将它包装在 if DEBUG 中。

      --编辑

      这需要更多的努力,因为这只能在单元测试期间出现。为了解决这个问题,我使用了http://djangosnippets.org/snippets/1011/ 的 sn-p 并创建了一个 UITestCase 类:

      class UITestCase(SettingsTestCase):
          '''
          UITestCase handles setting the Pipeline settings correctly.
          '''
          def __init__(self, *args, **kwargs):
              super(UITestCase, self).__init__(*args, **kwargs)
      
          def setUp(self):
              self.settings_manager.set(
                  STATICFILES_STORAGE='pipeline.storage.NonPackagingPipelineStorage')
      

      现在我所有需要渲染包含压缩css标签的UI的测试都使用UITestCase而不是django.test.TestCase。

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,原来是因为我有

        TEST_RUNNER = 'djcelery.contrib.test_runner.CeleryTestSuiteRunner'
        

        我不明白如何,但它一定是与管道交互。删除该设置后,问题就消失了。

        我仍然需要强制 Celery 在测试期间变得渴望,所以我使用override_settings 进行需要它的测试:

        from django.test.utils import override_settings
        
        …
        
        class RegisterTestCase(TestCase):
        
            @override_settings(CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
                               CELERY_ALWAYS_EAGER=True,
                               BROKER_BACKEND='memory')
            def test_new(self):
                …
        

        【讨论】:

          【解决方案5】:

          这里也一样。参考这个问题:https://github.com/cyberdelia/django-pipeline/issues/277

          当我使用 py.test 时,我把它放在 conftest.py 中作为一种解决方法:

          import pytest
          from django.conf import settings
          
          def pytest_configure():
              # workaround to avoid django pipeline issue
              # refers to 
              settings.STATICFILES_STORAGE = 'pipeline.storage.PipelineStorage'
          

          【讨论】:

            【解决方案6】:

            我已经尝试过@jrothenbuhler 的解决方法,起初它会有所帮助.. 但是,由于某种原因,它再次开始失败并出现同样的错误 经过数小时的调试,我发现唯一有帮助的就是设置

            STATICFILES_STORAGE = 'pipeline.storage.NonPackagingPipelineStorage'

            直接在设置中... 不知道为什么,但它有效。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2023-04-09
              • 2013-08-29
              • 2011-01-29
              • 2013-06-14
              • 2014-08-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多