Django 1.8和鼻子:沖突模型?

[英]Django 1.8 and nose: conflicting models?


I have a Django application I recently upgraded to Django 1.8.4. I'm using nose 1.3.7 and django-nose 1.4.1 for my test runner to run over 200 integration and unit tests. Since upgrading both Django and nose, I'm finding that 12 of my tests fail with this same error:

我有一個Django應用程序,我最近升級到Django 1.8.4。我正在使用nose 1.3.7和django-nose 1.4.1為我的測試運行器運行200多個集成和單元測試。自從升級Django和鼻子后,我發現我的12個測試失敗並出現同樣的錯誤:

======================================================================
ERROR: Failure: RuntimeError (Conflicting 'c' models in application 'nose': <class 'account.tests.form_tests.TestAddress'> and <class 'nose.util.C'>.)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/me/venv/myproj/lib/python2.7/site-packages/nose/loader.py", line 523, in makeTest
    return self._makeTest(obj, parent)
  File "/Users/me/venv/myproj/lib/python2.7/site-packages/nose/loader.py", line 568, in _makeTest
    obj = transplant_class(obj, parent.__name__)
  File "/Users/me/venv/myproj/lib/python2.7/site-packages/nose/util.py", line 644, in transplant_class
    class C(cls):
  File "/Users/me/venv/myproj/lib/python2.7/site-packages/django/db/models/base.py", line 311, in __new__
    new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
  File "/Users/me/venv/myproj/lib/python2.7/site-packages/django/apps/registry.py", line 223, in register_model
    (model_name, app_label, app_models[model_name], model))
RuntimeError: Conflicting 'c' models in application 'nose': <class 'account.tests.form_tests.TestAddress'> and <class 'nose.util.C'>.

What's curious is that the form_tests.py module doesn't even reference TestAddress which is actually a class inside my "profiles" model:

令人好奇的是,form_tests.py模塊甚至沒有引用TestAddress,它實際上是我的“profiles”模型中的一個類:

# myprof/profile/models.py
class TestAddress(models.Model):
    user = models.OneToOneField(User, primary_key=True, unique=True)
    address_line_1 = models.CharField(max_length=30)
    address_line_2 = models.CharField(max_length=30, null=True, blank=True)
    city = models.CharField(max_length=30)
    region = models.CharField(max_length=30, null=True, blank=True)
    postal_code = models.CharField(max_length=10, null=True, blank=True)
    country = models.ForeignKey('Country')

    class Meta:
        db_table = 'test_address'

    def __unicode__(self):
        return u'%s' % (self.user.username)

When my tests need to generate an instance of the TestAddress class, I use a factory_boy (v. 2.5.2) factory:

當我的測試需要生成TestAddress類的實例時,我使用factory_boy(v.2.5.2)工廠:

# utils/factories.py
from profile.models import TestAddress

class UserFactory(factory.django.DjangoModelFactory):
class Meta:
    model = User
username = 'testuser'

class TestAddressFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = TestAddress
    user = factory.SubFactory('utils.factories.UserFactory')
    address_line_1 = '123 Main St.'
    address_line_2 = 'Apt. A'
    city = 'AnyCity'
    region = 'AnyRegion'
    postal_code = '12345'
    country = factory.SubFactory('utils.factories.CountryFactory')

I set breakpoints in the nose loader.py module and confirmed that loader sees "TestAddress" in "profile.models". However, there is a "parent.__name__" variable there which is set to "account.tests.model_tests". I have a couple of questions:

我在nose loader.py模塊中設置了斷點,並確認加載器在“profile.models”中看到“TestAddress”。但是,有一個“parent .__ name__”變量,它設置為“account.tests.model_tests”。我有一些問題:

1. Why is this occurring? 
2. Is there a way I can fix it?  
3. Is there some way I can get nose to tell me which tests are resulting in these runtime errors so that I can at least disable them if I can't fix the problem?  

I set "--verbosity=2" but that doesn't display the names of failing tests. I looked through the nose docs and didn't see anything. Worst case I can write a script to call every test individually and echo the test name before running it but that seems very ugly and time-consuming.

我設置“--verbosity = 2”,但不顯示失敗測試的名稱。我仔細檢查了鼻子文檔並沒有看到任何東西。最糟糕的情況我可以編寫一個腳本來單獨調用每個測試並在運行之前回顯測試名稱,但這看起來非常難看且耗時。

Thanks.

謝謝。

2 个解决方案

#1


0  

I ran into the same issue while porting my Django project from 1.6 to 1.8 and updating django-nose to 1.4.3.

我在將Django項目從1.6移植到1.8並將django-nose更新為1.4.3時遇到了同樣的問題。

It appears that with the new DiscoverRunner used in 1.7 onwards, django-nose attempts to run all classes beginning with Test* as Test Cases, which leads to them being adapted into django-nose's django app before they are encountered in test modules.

似乎在1.7以后使用新的DiscoverRunner,django-nose嘗試以Test *作為測試用例運行所有類,這導致它們在測試模塊中遇到之前被調整到django-nose的django應用程序中。

I managed to resolve this issue by renaming them to avoid this naming scheme, to things like AdressTestModel.

我設法通過重命名它們以避免這種命名方案來解決這個問題,比如AdressTestModel。

#2


0  

I just encountered this and solved it with the @nottest decorator.

我剛剛遇到這個並用@nottest裝飾器解決了它。

Technically, it's for functions according to the docs, but decorating classes with it also works:

從技術上講,它是根據文檔的功能,但用它裝飾類也有效:

from nose.tools import nottest                                                  
@nottest
class TestAddressFactory(...):
   ...

All the decorator does is add __test__ with the value True to the object it is decorating.

所有裝飾器都會添加__test__,其值為True,正在裝飾它的對象。

def nottest(func):
    """Decorator to mark a function or method as *not* a test
    """
    func.__test__ = False
    return func

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2015/09/21/725831ada0b5b11217473adaf1707b4.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com