【问题标题】:Django : testing static filesDjango:测试静态文件
【发布时间】:2025-11-26 16:55:02
【问题描述】:

使用 Django 1.3 的测试框架(TestCase),我想对静态文件(即,django 本身在 prod 上不一定提供但可以用于调试(runserver)的文件)运行一些测试。 但是如果我运行

self.client.get("/static/somefile.json")

... 我在测试中遇到 404 错误。 (当然,这个文件在runserver上可用)

为什么不呢,但是在我的静态文件中检查这个 json 模式是否存在的最好方法是什么? (在我的情况下,我还想针对生成的 json 输出测试这个公共 json 模式,所以我想要文件的内容)

【问题讨论】:

标签: django testing


【解决方案1】:

我发现另一种方法稍微容易一些,因为输入/导入的内容更少:

from django.contrib.staticfiles import finders

result = finders.find('css/base.css')

如果找到静态文件,它将返回文件的完整路径。如果没有找到,会返回None

来源:https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#finders-module


从 Django 1.7+ 开始,您还可以通过查找器模块找出/测试 Django 正在查找的位置:

searched_locations = finders.searched_locations

除了 Django 提供的SimpleTestCase.assertTemplateUsed(response, template_name, msg_prefix='') 断言之外,您还可以使用: response.templates 从 Response 类获取用于呈现响应的模板列表。

来源:https://docs.djangoproject.com/en/dev/topics/testing/tools/#django.test.Response.templates

【讨论】:

  • 这会在我上传内容的测试中引发 SuspiciousFileOperation
【解决方案2】:

这个怎么样:

from django.contrib.staticfiles import finders
from django.contrib.staticfiles.storage import staticfiles_storage

absolute_path = finders.find('somefile.json')
assert staticfiles_storage.exists(absolute_path)

这使用静态文件查找器查找名为“somefile.json”的文件,然后检查该文件是否确实存在于您配置的存储中?

【讨论】:

  • 不像我希望的那样透明,但应该可以。我会尽快验证这一点。谢谢
  • staticfiles_storage.exists() 如果您设置了 STATIC_ROOTSTATIC_URL 不同,则可能会抛出 SuspiciousFileOperation 异常,因为测试用例不收集静态文件;你实际上并不需要这个,因为如果路径无效,finders.find 将返回 none
【解决方案3】:

您可以使用 staticfiles 模块中的 testing.StaticLiveServerTestCase 类: http://django.readthedocs.org/en/latest/ref/contrib/staticfiles.html#specialized-test-case-to-support-live-testing

【讨论】:

  • 这是使用实时测试服务器时的正确答案!
【解决方案4】:

作为 isbadawi cmets,测试服务器始终以DEBUG = False 运行。所以你不能依赖 DEBUG 处理静态文件,你需要一种明确的生产方式来处理它们,以便测试找到它们。您可以在您的 urls.py 中有一个特殊部分,当您运行 test 时打开开发 serve()

if 'test' in sys.argv:
    static_url = re.escape(settings.STATIC_URL.lstrip('/'))
    urlpatterns += patterns('',
        url(r'^%s(?P<path>.*)$' % static_url, 'django.views.static.serve', {
            'document_root': settings.STATIC_ROOT,
        }),
    )

【讨论】:

  • +1 表示独创性,但如果您要更改 ernvironment 变量以使测试通过,感觉它会破坏单元测试的意义
【解决方案5】:

【讨论】:

    【解决方案6】:

    FWIW,对于重要的项目,我认为测试静态文件可能超出了纯 Django 测试的范围,因为 Django 的运行服务器不打算用于提供静态文件。这种测试通常是为集成测试保留的,这些测试涉及比开发代码更多地测试您的部署。

    【讨论】: