2015-01-30 13 views
12

È possibile passare argomenti della riga di comando allo script manage.py di Django, in particolare per i test delle unità? vale a dire se faccio qualcosa di simileDjango manage.py: è possibile passare l'argomento della riga di comando (per il test dell'unità)

manage.py test myapp -a do_this 

Posso ricevere il valore do_this nella funzione setUp di test di unità?

P.S. @ Martin ha chiesto la giustificazione per l'utilizzo di argomenti della riga di comando nei test:

  • Alcune prove approfondite prendono un sacco di tempo e non hanno bisogno di essere eseguito prima di ogni invio. Voglio renderle opzionali.

  • messaggi di debug occasionali stampati dai miei casi di test dovrebbe essere facoltativo

  • A volte voglio solo i test per impazzire e cercare molto di più permutazioni di dati.

Tutto quanto sopra sarebbe abbastanza conveniente con le opzioni della riga di comando. Una volta ogni tanto il test può essere molto più esteso o prolisso, altrimenti sarà veloce.

+0

Indipendentemente dal sì o dal no, non avrebbe più senso aggiungere gli argomenti al test dell'unità stesso? Questo è veramente uno dei principali casi d'uso di un test unitario: controllo di diversi casi limite ecc. Se definisci diverse funzioni di test per ciascun caso, sarai in grado di chiamarli separatamente come 'manage.py test myapp.mytestcase' –

+0

@ Martin Punto giusto.Ho elaborato i miei pensieri nella risposta (P.S.) – user4150760

+0

ok, quindi creerei funzioni come 'testBasic',' testCrazy' ecc. Ed eseguo qualsiasi test necessario su commit. Sono completamente d'accordo sul fatto che eseguire un'intera suite di test di un grande progetto su ogni commit può essere fastidioso. Ecco perché dovresti creare un nuovo test per un commit o semplicemente scegliere il test a cui è legato il commit. –

risposta

2

In un modo alternativo per manage.py test -a do_this è possibile utilizzare specifici settings file

manage.py --settings=project.test_settings test 

e definire in questo file quello che vuoi.

# test_setting.py 
SPECIFIC_OPTION = "test" 

# tests.py 
from django.conf import settings 
... 
def setUp(self): 
    if settings.SPECIFIC_OPTION: 
     .... 

Se avete bisogno di opzioni davvero dinamici, forse è possibile utilizzare sys.argv in test_settings.py, ma è un hack davvero sporca.

+0

Grazie per aver suggerito questa soluzione alternativa. Hai detto: 'puoi usare sys.argv in test_settings.py, ma è un trucco molto sporco ': puoi elaborare? – user4150760

+1

È possibile passare qualsiasi argomento alla riga di comando: '$ manage.py --settings = test_settings prova some-specific-option', e quindi usa qualcosa di simile in' test_settings.py': 'if sys.argv [-1] == "qualcosa": # do stuff' (e dopo tutto devi abbandonare questo argomento extra: 'del sys.argv [-1]') – erthalion

6

sto usando le variabili di ambiente soluzione alternativa nel mio progetto (funziona solo in shell Unix-like)

berry$ myvar=myval ./manage.py test 

nel vostro modulo di leggere questo valore utilizzando

os.environ.get('myvar') 
3

Ho appena incontrato questo problema me stesso, e volevo evitare di impostare variabili ambientali sulla riga di comando. Le variabili ambientali funzionano certamente, ma è difficile tenere traccia di quali variabili hanno un effetto e non vi è alcun messaggio di errore per informarti se hai digitato erroneamente uno di essi.

Per aggirare questo ho usato argparse per estrarre parametri aggiuntivi all'argomento della riga di comando. Per esempio, il mio file manage.py ora simile a questa:

#!/usr/bin/env python 
import os 
import sys 
import argparse 


if __name__ == "__main__": 
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") 

    argv = sys.argv 
    cmd = argv[1] if len(argv) > 1 else None 
    if cmd in ['test']: # limit the extra arguments to certain commands 
     parser = argparse.ArgumentParser(add_help=False) 
     parser.add_argument('--foo', default='bar') 
     args, argv = parser.parse_known_args(argv) 
     # We can save the argument as an environmental variable, in 
     # which case it's to retrieve from within `project.settings`, 
     os.environ['FOO'] = args.foo 
     # or we can save the variable to settings directly if it 
     # won't otherwise be overridden. 
     from django.conf import settings 
     settings.foo = args.foo 

    from django.core.management import execute_from_command_line 

    # parse_known_args strips the extra arguments from argv, 
    # so we can safely pass it to Django. 
    execute_from_command_line(argv) 

argparse è davvero un bella libreria con un sacco di funzioni. C'è un buon tutorial su di esso nei documenti Python.