2014-09-04 12 views
13

Sto provando a trasferire il mio progetto per utilizzare Django 1.7. Va tutto bene tranne 1 cosa. Modelli all'interno delle cartelle di test.Modelli all'interno di test - numero di Django 1.7

Le nuove migrazioni di Django 1.7 eseguono il comando di migrazione internamente. Prima che syncdb fosse eseguito. Ciò significa che se un modello non è incluso nelle migrazioni, non verrà popolato in DB (e anche per testare il DB). Questo è esattamente ciò che sto vivendo in questo momento.

Quello che faccio è:

Nel mio /app/tests/models.py ho modello dummy: class TestBaseImage(BaseImage): pass Tutto ciò che fa è quello di ereditare da un abstract modello BaseImage.

Quindi nei test creo le istanze di quel modello fittizio per testarlo.

Il problema è che non funziona più. Non è incluso nelle migrazioni (è ovvio che non voglio mantenere i miei modelli di test in un DB di produzione). L'esecuzione dei miei test causa l'errore del DB che dice che table does not exist. Questo ha senso in quanto non è incluso nelle migrazioni.

Esiste un modo per farlo funzionare con il nuovo sistema di migrazione? Non riesco a trovare un modo per "risolvere" quello.

codice che utilizzo:

app/test/models.py

from ..models import BaseImage 


class TestBaseImage(BaseImage): 
    """Dummy model just to test BaseImage abstract class""" 
    pass 

app/models.py

class BaseImage(models.Model): 
    # ... fields ... 
    class Meta: 
     abstract = True 

fabbriche:

class BaseImageFactory(factory.django.DjangoModelFactory): 
    """Factory class for Vessel model""" 
    FACTORY_FOR = BaseImage 
    ABSTRACT_FACTORY = True 


class PortImageFactory(BaseImageFactory): 
    FACTORY_FOR = PortImage 

esempio di prova:

def get_model_field(model, field_name): 
    """Returns field instance""" 
    return model._meta.get_field_by_name(field_name)[0] 


def test_owner_field(self): 
    """Tests owner field""" 
    field = get_model_field(BaseImage, "owner") 

    self.assertIsInstance(field, models.ForeignKey) 
    self.assertEqual(field.rel.to, get_user_model()) 
+0

Ho creato un nuovo modello in test e ne ho creato istanze, ma non ricevo alcun errore. – ChillarAnand

+0

@ChillarAnand Ho aggiunto del codice. Lo hai fatto usando Django 1.7 e il sud spento? Ho ancora la tabella non esiste:/ – tunarob

+0

Non dovrebbe essere il tuo oggetto deriso e non definito in questo modo? – aRkadeFR

risposta

5

C'è un biglietto di richiesta di un modo per fare modelli di prova per soli here

Per risolvere il problema, è possibile separare la vostra tests.py e renderlo un app.

tests 
|--migrations 
|--__init__.py 
|--models.py 
|--tests.py 

vi ritroverete con qualcosa di simile:

myapp 
|-migrations 
|-tests 
|--migrations 
|--__init__.py 
|--models.py 
|--tests.py 
|-__init__.py 
|-models.py 
|-views.py 

allora si dovrebbe aggiungere al tuo INSTALLED_APPS

INSTALLED_APPS = (
    # ... 
    'myapp', 
    'myapp.tests', 
) 

Probabilmente non si vuole installare myapp.tests nella produzione, in modo da poter tenere separati i file delle impostazioni. Qualcosa del genere:

INSTALLED_APPS = (
    # ... 
    'myapp', 
) 

try: 
    from local_settings import * 
except ImportError: 
    pass 

O meglio ancora, creare un corridore di prova e installare i test lì.

Ultimo ma non meno importante, ricordarsi di eseguire python manage.py makemigrations

+0

Questa soluzione causerebbe l'esistenza del modello di test come tabella nel database di produzione, giusto? Questo è inaccettabile. – Rico

+3

No, la risposta indica di usare file di impostazioni separate per test vs prod, per evitare che il modello di test venga creato in produzione. –

3

Ecco una soluzione che sembra funzionare. Trucca il framework di migrazione pensando che non ci siano migrazioni per la tua app. In settings.py:

if 'test' in sys.argv: 
    # Only during unittests... 

    # myapp uses a test-only model, which won't be loaded if we only load 
    # our real migration files, so point to a nonexistent one, which will make 
    # the test runner fall back to 'syncdb' behavior. 
    MIGRATION_MODULES = { 
     'myapp': 'myapp.migrations_not_used_in_tests' 
    } 

ho trovato l'idea sulla first post in ths Django dev mailing list thread, ed è anche attualmente in uso in Django itself, ma potrebbe non funzionare nelle future versioni di Django in cui sono richieste le migrazioni e la "syncdb fallback" viene rimosso.

Problemi correlati