2010-10-01 15 views
40

Czy mogę uruchomić testy mojej aplikacji Django do wielokrotnego użytku bez włączania tej aplikacji do projektu?Jak uruchomić testy dla aplikacji wielokrotnego użytku django?

Moja aplikacja korzysta z niektórych modeli, dlatego konieczne jest wprowadzenie ustawień (TEST_)DATABASE_*. Gdzie mam je przechowywać i jak uruchomić testy?

W przypadku projektu Django mogę wykonywać testy z manage.py test; kiedy używać django-admin.py test z moim samodzielny app, otrzymuję:

Error: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.

Jakie są najlepsze praktyki tutaj?

+0

Django nie wymaga projektu. O co pytasz? Czy uruchomiłeś test 'django-admin.py'? Co zaobserwowałeś? –

+0

dla projektu django uruchamiam testy przez: test manage.py, gdy używam django-admin.py dostaję: Błąd: ustawień nie można zaimportować, ponieważ zmienna środowiskowa DJANGO_SETTINGS_MODULE jest niezdefiniowana. Wierzę, że to musi być bardzo proste, ale utknąłem z tym. – dzida

Odpowiedz

18

mam zakończył takiego rozwiązania (został zainspirowany rozwiązania znalezionego w django głosowania):

Utwórz plik np. „Runtests.py” w reż testy zawierające:

import os, sys 
from django.conf import settings 

DIRNAME = os.path.dirname(__file__) 
settings.configure(DEBUG = True, 
        DATABASE_ENGINE = 'sqlite3', 
        DATABASE_NAME = os.path.join(DIRNAME, 'database.db'), 
        INSTALLED_APPS = ('django.contrib.auth', 
            'django.contrib.contenttypes', 
            'django.contrib.sessions', 
            'django.contrib.admin', 
            'myapp', 
            'myapp.tests',)) 


from django.test.simple import run_tests 

failures = run_tests(['myapp',], verbosity=1) 
if failures: 
    sys.exit(failures) 

Pozwala na przeprowadzanie testów przez komendę python runtests.py. Nie wymaga zainstalowanych zależności (np. Buildout) i nie szkodzi testom uruchamianym, gdy aplikacja jest włączona do większego projektu.

5

Do mojej aplikacji wielokrotnego użytku (django-moderation) Używam buildout. Tworzę example_project, używam go z buildout, aby uruchomić testy na nim. Po prostu umieszczam swoją aplikację w ustawieniach example_project.

Kiedy chcę zainstalować wszystkie zależności używane przez mojego projektu i uruchomić testy, tylko trzeba zrobić następujące:

  • Run: Python bootstrap.py
  • Run buildout:

    bin/buildout

  • testy wykonywane dla Django 1.1 i 1.2: Django

    bin/test-1,1 bin/test-1,2

Tutaj można znaleźć poradnik jak skonfigurować wielokrotnego użytku aplikację do korzystania buildout do wdrożenia i testy zakończą: http://jacobian.org/writing/django-apps-with-buildout/

Tutaj znajdziesz przykładowy buildout config który używam w moim projekcie:

http://github.com/dominno/django-moderation/blob/master//buildout.cfg

+0

Dzięki za przydatne informacje. Zobaczymy, czy to rozwiąże mój problem (na pierwszy rzut oka wygląda na dużo kłopotów), ale może być interesujące dla innych celów. – dzida

43

prawidłowe użycie Django (> = 1,4) Badanie płoza jest następujący:

import django, sys 
from django.conf import settings 

settings.configure(DEBUG=True, 
       DATABASES={ 
        'default': { 
         'ENGINE': 'django.db.backends.sqlite3', 
        } 
       }, 
       ROOT_URLCONF='myapp.urls', 
       INSTALLED_APPS=('django.contrib.auth', 
           'django.contrib.contenttypes', 
           'django.contrib.sessions', 
           'django.contrib.admin', 
           'myapp',)) 

try: 
    # Django <= 1.8 
    from django.test.simple import DjangoTestSuiteRunner 
    test_runner = DjangoTestSuiteRunner(verbosity=1) 
except ImportError: 
    # Django >= 1.8 
    django.setup() 
    from django.test.runner import DiscoverRunner 
    test_runner = DiscoverRunner(verbosity=1) 

failures = test_runner.run_tests(['myapp']) 
if failures: 
    sys.exit(failures) 

DjangoTestSuiteRunner i DiscoverRunner mają zasadniczo kompatybilne interfejsów.

Aby uzyskać więcej informacji, należy zapoznać się z "Definiowanie Runner Test" docs:

9

Dla Django 1.7 jest nieco inny. Zakładając, że mamy następującą strukturę katalogów dla aplikacji foo:

foo 
|── docs 
|── foo 
│ ├── __init__.py 
│ ├── models.py 
│ ├── urls.py 
│ └── views.py 
└── tests 
    ├── foo_models 
    │ ├── __init__.py 
    │ ├── ... 
    │ └── tests.py 
    ├── foo_views 
    │ ├── __init__.py 
    │ ├── ... 
    │ └── tests.py 
    ├── runtests.py 
    └── urls.py 

ten sposób Sam projekt Django struktury swoich testów.

Chcesz uruchomić wszystkie testy w foo/tests/ z poleceniem:

python3 runtests.py 

także chcą, aby móc uruchomić polecenie z katalogu nadrzędnego, np tests przez Tox lub Invoke, tak jak python3 foo/tests/runtests.py.

Rozwiązanie, które tutaj przedstawiam, jest dość wielokrotnego użytku, należy zmienić tylko nazwę aplikacji foo (i dodatkowe aplikacje, jeśli to konieczne). Mogą nie być instalowane za pośrednictwem modify_settings, ponieważ będzie to brakowało konfiguracji bazy danych.

potrzebne są następujące pliki:

urls.py

""" 
This urlconf exists because Django expects ROOT_URLCONF to exist. URLs 
should be added within the test folders, and use TestCase.urls to set them. 
This helps the tests remain isolated. 
""" 

urlpatterns = [] 

runtests.py

#!/usr/bin/env python3 
import glob 
import os 
import sys 

import django 
from django.conf import settings 
from django.core.management import execute_from_command_line 


BASE_DIR = os.path.abspath(os.path.dirname(__file__)) 
sys.path.append(os.path.abspath(os.path.join(BASE_DIR, '..'))) 

# Unfortunately, apps can not be installed via ``modify_settings`` 
# decorator, because it would miss the database setup. 
CUSTOM_INSTALLED_APPS = (
    'foo', 
    'django.contrib.admin', 
) 

ALWAYS_INSTALLED_APPS = (
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
) 

ALWAYS_MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.contrib.messages.middleware.MessageMiddleware', 
    'django.middleware.clickjacking.XFrameOptionsMiddleware', 
) 


settings.configure(
    SECRET_KEY="django_tests_secret_key", 
    DEBUG=False, 
    TEMPLATE_DEBUG=False, 
    ALLOWED_HOSTS=[], 
    INSTALLED_APPS=ALWAYS_INSTALLED_APPS + CUSTOM_INSTALLED_APPS, 
    MIDDLEWARE_CLASSES=ALWAYS_MIDDLEWARE_CLASSES, 
    ROOT_URLCONF='tests.urls', 
    DATABASES={ 
     'default': { 
      'ENGINE': 'django.db.backends.sqlite3', 
     } 
    }, 
    LANGUAGE_CODE='en-us', 
    TIME_ZONE='UTC', 
    USE_I18N=True, 
    USE_L10N=True, 
    USE_TZ=True, 
    STATIC_URL='/static/', 
    # Use a fast hasher to speed up tests. 
    PASSWORD_HASHERS=(
     'django.contrib.auth.hashers.MD5PasswordHasher', 
    ), 
    FIXTURE_DIRS=glob.glob(BASE_DIR + '/' + '*/fixtures/') 

) 

django.setup() 
args = [sys.argv[0], 'test'] 
# Current module (``tests``) and its submodules. 
test_cases = '.' 

# Allow accessing test options from the command line. 
offset = 1 
try: 
    sys.argv[1] 
except IndexError: 
    pass 
else: 
    option = sys.argv[1].startswith('-') 
    if not option: 
     test_cases = sys.argv[1] 
     offset = 2 

args.append(test_cases) 
# ``verbosity`` can be overwritten from command line. 
args.append('--verbosity=2') 
args.extend(sys.argv[offset:]) 

execute_from_command_line(args) 

Niektóre ustawienia są opcjonalne; poprawiają szybkość lub bardziej realistyczne środowisko.

Drugi argument wskazuje na bieżący katalog. Korzysta z feature of providing a path to a directory to discover tests below that directory.

+0

Świetna odpowiedź! Dodałem '__init __. Py' do'/tests/', aby działało. – Mikke

+0

W większości przypadków udało mi się uniknąć tworzenia podkatalogów dla moich aplikacji w katalogu 'tests', ustawiając po prostu' test_cases = '..' 'zamiast (aby umożliwić mi przestrzeganie konwencji posiadania tests.py w folderach aplikacji). Bardzo dobra odpowiedź! – Sayse

Powiązane problemy