2015-09-21 19 views
8

Ho un'applicazione Django che ho recentemente aggiornato a Django 1.8.4. Sto usando il naso 1.3.7 e il 1.4.1 del django-nose per il mio runner di test per eseguire oltre 200 test di integrazione e unità. Dal momento che l'aggiornamento sia Django e il naso, ho constatato che 12 dei miei test riuscire con questo stesso errore:Django 1.8 e naso: modelli in conflitto?

====================================================================== 
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'>. 

Cosa c'è di curioso è che il modulo form_tests.py non ha nemmeno riferimento TestAddress che è in realtà una classe all'interno il mio modello "profili":

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

Quando i miei test devono generare un'istanza della classe TestAddress, io uso un factory_boy (v 2.5.2.) fabbrica:

# 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') 

ho impostato i punti di interruzione nel modulo nose loader.py e confermato che il loader vede "TestAddress" in "profile.models". Tuttavia, esiste una variabile "parent .__ name__" che è impostata su "account.tests.model_tests". Ho un paio di domande:

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? 

ho impostato "--verbosity = 2", ma che non visualizza i nomi dei test fallimento. Ho guardato attraverso i documenti del naso e non ho visto nulla. Nel peggiore dei casi, posso scrivere uno script per chiamare ogni test singolarmente ed echo il nome del test prima di eseguirlo, ma sembra molto brutto e richiede molto tempo.

Grazie.

risposta

0

Ho riscontrato lo stesso problema durante il porting del mio progetto Django dalla 1.6 alla 1.8 e l'aggiornamento di django-nose alla 1.4.3.

Sembra che con il nuovo DiscoverRunner utilizzato in 1.7 in poi, i tentativi django-naso per eseguire tutte le classi iniziano con Test* come casi di test, che porta a loro di essere adattati in django app django-naso prima che si incontrano in moduli di test .

Sono riuscito a risolvere questo problema rinominandoli per evitare questo schema di denominazione, a cose come AdressTestModel.

0

L'ho appena incontrato e l'ho risolto con il decoratore @nottest.

Tecnicamente, è per le funzioni Secondo la documentazione, ma le classi di decorazione con funziona anche:

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

Tutto il decoratore non è aggiungere __test__ con il valore True all'oggetto che sta decorando.

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