我收到以下错误:


  (testassets)➜testassets git:(master)✗django-admin.py测试
      正在为别名“默认”创建测试数据库...
      Ë
      ================================================== ====================
      错误:test_get_site_root_with_settings_overrides(app.tests.AssetsTestCase)
      -------------------------------------------------- --------------------
      追溯(最近一次通话):
        在test_get_site_root_with_settings_overrides中,文件“ /Volumes/fifteen5cs/testassets/app/tests.py”,第27行
          http_client.get('/')
        在获得的文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/test/client.py”中,行473
          响应=超级(客户,自我).get(路径,数据=数据,**额外)
        在获得的文件“ /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”
          six.reraise(* exc_info)
        get_response中的文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/core/handlers/base.py”,第114行
          响应= wraped_callback(请求,* 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/init.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(上下文)
        在Instrumented_test_render中,文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/test/utils.py”第85行
          返回self.nodelist.render(上下文)
        渲染中的文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/template/base.py”,第840行
          位= self.render_node(节点,上下文)
        在render_node中,文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django/template/debug.py”,第78行
          返回node.render(上下文)
        渲染中的文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django_assets/templatetags/assets.py”,第72行
          对于bundle.urls()中的url:
        网址中的文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py”,第783行
          对于self.iterbuild(ctx)中的bundle,extra_filters和new_ctx:
        在iterbuild中的文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py”,第679行
          对于包,_在self.resolve_contents(ctx)中:
        文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py”,行233,位于resolve_contents中
          结果= ctx.resolver.resolve_source(ctx,项目)
        在getattr中的文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py”,第50行
          返回self.getattr(self._parent,item)
        在getattr文件的第58行,输入文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/bundle.py”
          返回getattr(object,item)
        _get_resolver中的第675行“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/webassets/env.py”
          返回self._storage ['resolver']
        在getitem中的文件“ /Users/paul/.pyenv/versions/testassets/lib/python2.7/site-packages/django_assets/env.py”,第62行
          self._transform_key(key))
      KeyError:“ Django设置未定义RESOLVER”


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

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


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

  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()

最佳答案

事实证明,此问题是由于禁用任何django_assets.env.env后未重置override_settings单例的缘故。此单例对象未在'settings'对象之间重建的事实意味着,如果django_assets.env.env对象是在覆盖设置的上下文中构建的,则当这些覆盖设置替换为非覆盖设置时,所有添加到临时设置模块通过创建django_assets.env.env对象将丢失。 RESOLVERASSETS_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_LOADED更新为False,并从assets.py删除每个应用程序的sys.modules文件。我们必须更新_ASSETS_LOADED,以便django-assets尝试在下次调用django_assets.env.get_env时重新导入每个应用程序的资产文件。调用django_assets.env.get_env还将重建env._bundle_names词典。最后,我们必须从sys.modules中删除每个应用程序的资产模块。否则,__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']


顺便说一句,我很想提出其他解决此问题的方法的建议。

10-04 10:05