2

我收到以下错误:

(testassets)➜ testassets git:(master) ✗ django-admin.py test 为别名'default'创建测试数据库... E ==================== ================================================== 错误: test_get_site_root_with_settings_overrides (app.tests.AssetsTestCase) ----------------------------------------- ----------------------------- Traceback(最近一次通话最后):文件“/Volumes/fifteen5cs/testassets/app/tests. py”,第 27 行,test_get_site_root_with_settings_overrides http_client.get('/') 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/test/client.py”,行473、在get response = super(Client, self).get(path, data=data, **extra) File "/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/test/client.py”,第 280 行,在获取返回 self.request(**r) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site -packages/django/test/client.py”,第 444 行,在请求 6.reraise(*exc_info) 文件中“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/ core/handlers/base.py”,第 114 行,在 get_response response = Wrapped_callback(request, *callback_args, **callback_kwargs) 文件“/Volumes/fifteen5cs/testassets/app/views.py”,第 9 行,索引 context_instance= RequestContext(请求))文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/shortcuts/pyenv/versions/testassets/lib/python2.7/site-packages/django/test/client.py”,第 444 行,请求 6.reraise(*exc_info) 文件“/Users/paul/.pyenv/versions/testassets /lib/python2.7/site-packages/django/core/handlers/base.py”,第 114 行,在 get_response 响应 = Wrapped_callback(request, *callback_args, **callback_kwargs) 文件“/Volumes/fifteen5cs/testassets/app /views.py”,第 9 行,索引 context_instance=RequestContext(request)) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/shortcuts/pyenv/versions/testassets/lib/python2.7/site-packages/django/test/client.py”,第 444 行,请求 6.reraise(*exc_info) 文件“/Users/paul/.pyenv/versions/testassets /lib/python2.7/site-packages/django/core/handlers/base.py”,第 114 行,在 get_response 响应 = Wrapped_callback(request, *callback_args, **callback_kwargs) 文件“/Volumes/fifteen5cs/testassets/app /views.py”,第 9 行,索引 context_instance=RequestContext(request)) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/shortcuts/第 114 行,在 get_response response = Wrapped_callback(request, *callback_args, **callback_kwargs) 文件“/Volumes/fifteen5cs/testassets/app/views.py”,第 9 行,在索引 context_instance=RequestContext(request)) 文件“/Users /paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/shortcuts/第 114 行,在 get_response response = Wrapped_callback(request, *callback_args, **callback_kwargs) 文件“/Volumes/fifteen5cs/testassets/app/views.py”,第 9 行,在索引 context_instance=RequestContext(request)) 文件“/Users /paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/shortcuts/在里面.py”,第 29 行,在 render_to_response 返回 HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site- packages/django/template/loader.py”,第 169 行,在 render_to_string 返回 t.render(context_instance) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/template /base.py”,第 140 行,在渲染中返回 self._render(context) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/test/utils.py” ,第 85 行,instrumented_test_render 返回 self.nodelist.render(context) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/template/base.py”,第 840 行,在渲染位 = self.render_node(node, context) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/template/debug.py”,第 78 行,在 render_node返回 node.render(context) 文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django_assets/templatetags/assets.py”,第 72 行,在 bundle 中为 url 渲染。 urls():文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py”,第 783 行,在 self.iterbuild 中 bundle、extra_filters、new_ctx 的 url (ctx):文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py”,第 679 行,在 iterbuild for bundle 中,_ 在 self.resolve_contents(ctx ):文件“/用户/保罗/。pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py”,第 233 行,在 resolve_contents 结果 = ctx.resolver.resolve_source(ctx, item) 文件“/Users/paul/.pyenv/版本/testassets/lib/python2.7/site-packages/webassets/bundle.py”,第 50 行,在getattr return self.getattr(self._parent, item) File "/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py",第 58 行,在 getattr return getattr (对象,项目)文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/env.py”,第 675 行,在 _get_resolver 返回 self._storage['resolver']文件“/Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django_assets/env.py”,第 62 行,在getitem self._transform_key (key)) KeyError:“Django 设置没有” t 定义 RESOLVER"

----------------------------------------------------------------------
Ran 1 test in 0.325s

FAILED (errors=1)
Destroying test database for alias 'default'...

我已将此错误半链接到在django.test.utils.override_settings我的一个单元测试中使用 Django utils 函数(如下所示)

  1 from django.test.utils import override_settings
  2 from django.utils.unittest.case import TestCase
  3 from django.test.client import Client
  4
  5
  6 OVERRIDE_SETTINGS = {
  7     'DEBUG': True,
  8     'ASSETS_DEBUG': True,
  9     'ASSETS_AUTO_BUILD': True,
 10     'ASSETS_URL_EXPIRE': False,
 11     'ASSETS_CACHE': False,
 12     'ASSETS_MANIFEST': False,
 13     'ASSETS_VERSIONS': False,
 14 }
 15
 16
 17 class AssetsTestCase(TestCase):
 18     def test_get_site_root_with_settings_overrides(self):
 19         http_client = Client()
 20         # import pdb;pdb.set_trace()
 21         settings_override = override_settings(**OVERRIDE_SETTINGS)
 22         settings_override.enable()
 23         http_client.get('/')
 24         settings_override.disable()
 25
 26         settings_override.enable()
 27         http_client.get('/')
 28         settings_override.disable()

(注意。在第二次请求期间引发了异常!)

我正在处理的第一个问题的代码库太大且无法共享,因此我已将项目精简为仍然会产生问题的少量代码。该迷你项目可以在这里找到https://github.com/logston/testassets

我花了两天多的时间试图确定这个错误的确切来源以及为什么它在第二个请求而不是第一个请求中发生。我已经尝试了许多单元测试的排列。有趣的是,如果我创建第二个单元测试,一个不启用设置覆盖的单元测试(例如下面的那个)并将该测试命名为在测试期间首先运行,则测试套件通过。如果我在单元测试之后放置相同的test_get_site_root_with_settings_overrides单元测试,两者都会失败。

      def test_get_site_root(self):
          http_client = Client()
          http_client.get('/')

          http_client.get('/')

对此问题的任何帮助将不胜感激。

最后,我能找到的唯一一个提到相同或类似问题的问题在这里:https ://github.com/miracle2k/django-assets/issues/44

更新 2015/01/12

这个问题似乎与信号的使用有关。我已将上述失败的测试简化为以下内容:

from django.test.utils import override_settings
from django.utils.unittest.case import TestCase
from django_assets.env import get_env


class AssetsTestCase(TestCase):
    def test(self):
        settings_override = override_settings()
        settings_override.enable()
        get_env().resolver
        settings_override.disable()

        settings_override.enable()
        get_env().resolver
        settings_override.disable()
4

1 回答 1

3

原来这个问题是由于django_assets.env.env禁用任何override_settings. 这个单例对象没有在“设置”对象之间重建这一事实意味着,如果一个 django_assets.env.env对象是在覆盖设置的上下文中构建的,当这些覆盖设置被替换为非覆盖设置时,任何添加到临时设置模块的常量被创建的django_assets.env.env对象会丢失。RESOLVER并且ASSETS_CACHE是将丢失的常量的绝佳示例。为了避免这种损失,我们必须确保在设置模块更改后django_assets.env.env通过调用来重置对象。django_assets.env.reset调用reset将强制 django-assets 在下次调用时将这些常量重新插入到当前设置模块中django_assets.env.get_env

不幸的是,调用django_assets.env.reset会导致django_assets.env.env._bundle_names字典被清空(nb。实际上它被破坏并构建了一个新字典)。该字典的丢失会导致如下错误:

BundleError: %s not found (using staticfiles finders)

要解决此问题,我们必须更新django_assets.env._ASSETS_LOADEDFalse删除每个应用程序的assets.py文件sys.modules。我们必须进行更新_ASSETS_LOADED,以便 django-assets 在下次 django_assets.env.get_env调用时尝试重新导入每个应用程序的资产文件。调用也 django_assets.env.get_env将重建env._bundle_names字典。最后,我们必须从 sys.modules 中删除每个应用程序的 assets 模块。否则,__import__('app.assets')将不会导入(读取“执行”)资产模块,因为资产模块已经导入!

因此,这个问题的完整解决方案如下所示:

import sys

from django_assets import env as assets_env

settings_override = override_settings(**OVERRIDE_SETTINGS)
settings_override.enable()
... do things ...
settings_override.disable()
assets_env.reset()
assets_env._ASSETS_LOADED = False
del sys.modules['<app_name>.assets']

顺便说一句,我很乐意听取有关解决此问题的其他方法的建议。

于 2015-01-13T07:02:32.007 回答