2015-01-30 22 views
12

Czy można przekazywać argumenty wiersza poleceń do skryptu Django manage.py, w szczególności do testów jednostkowych? to znaczy, jeśli zrobię coś podobnegoDjango manage.py: Czy możliwe jest przekazanie argumentu wiersza poleceń (do testowania jednostkowego)?

manage.py test myapp -a do_this 

Czy mogę otrzymać wartość do_this w funkcji setUp od badanej jednostki?

P.S. @Martin poprosił uzasadnienie zastosowania argumenty wiersza poleceń w testach:

  • Niektóre rozległe testy miały dużo czasu i nie muszą być wykonywane przed każdym popełnić. Chcę, aby były opcjonalne.

  • okolicznościowe komunikaty debugowania drukowane przez moich testów powinny być opcjonalne

  • Czasami po prostu chcę testy zaszaleć i wypróbować wiele więcej permutacji danych.

Wszystkie powyższe byłoby całkiem wygodne z opcjami wiersza poleceń. Raz na jakiś czas testowanie może być dużo obszerniejsze lub bardziej szczegółowe, w przeciwnym razie będzie szybkie.

+0

Niezależnie od tak lub nie, czy nie ma większego sensu dodawanie argumentów do samego testu jednostki? To naprawdę jeden z głównych przypadków użycia testu jednostkowego - sprawdzanie różnych przypadków skrajnych itp. Jeśli zdefiniujesz różne funkcje testowe dla każdego przypadku, będziesz mógł wywoływać je osobno, np. 'Manage.py test myapp.mytestcase' –

+0

@ Martin Fair point.Rozwinąłem swoje myśli w odpowiedzi (P.S.) – user4150760

+0

ok, a następnie utworzyłbym funkcje takie jak 'testBasic',' testCrazy' itd. I przeprowadziłbym dowolny test, którego potrzebujesz przy zatwierdzaniu. Całkowicie zgadzam się, że uruchomienie całego zestawu testów dużego projektu przy każdym zatwierdzeniu może być denerwujące - dlatego powinieneś stworzyć nowy test dla zatwierdzenia lub wybrać test, z którym związany jest commit. –

Odpowiedz

2

jako alternatywny sposób do manage.py test -a do_this można wykorzystać specyficzne settings file

manage.py --settings=project.test_settings test 

i określić w tym pliku co chcesz.

# test_setting.py 
SPECIFIC_OPTION = "test" 

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

Jeśli potrzebujesz naprawdę dynamiczne opcje, może użyć sys.argv w test_settings.py, ale jest to naprawdę brudne Hack.

+0

Dziękujemy za sugerowanie tego obejścia. Wspomniałeś: 'możesz użyć sys.argv w test_settings.py, ale jest to naprawdę brudny hack': Czy możesz rozwinąć? – user4150760

+1

Możesz przekazać dowolne argumenty do wiersza poleceń: '$ manage.py --settings = test_settings przetestuj pewną konkretną opcję ', a następnie użyj czegoś takiego w' test_settings.py': 'if sys.argv [-1] == "coś": # do rzeczy "(i musisz porzucić tę dodatkową argumentację:' del sys.argv [-1] ') – erthalion

6

używam obejścia zmienne środowiskowe w moim projekcie (działa tylko w systemie UNIX, takich jak muszle)

berry$ myvar=myval ./manage.py test 

w module odczytać tę wartość za pomocą

os.environ.get('myvar') 
3

po prostu wpadł na ten problem siebie i chciałem uniknąć ustawiania zmiennych środowiskowych w linii poleceń. Zmienne środowiskowe z pewnością działają, ale trudno jest śledzić, które zmienne mają wpływ i nie ma komunikatu o błędzie, aby poinformować, jeśli źle wpisałeś jedną z nich.

Aby obejść ten problem, użyłem argparse, aby wyodrębnić dodatkowe parametry do argumentu wiersza poleceń. Na przykład, mój plik manage.py teraz wygląda tak:

#!/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 jest naprawdę ładne biblioteka z mnóstwem funkcji. W dokumentacji Pythona znajduje się dobry tutorial.