unitarias test pruebas parallel form django testing django-testing

test - ¿Cómo iniciar pruebas para la aplicación reutilizable django?



test form django (5)

El uso correcto de Django (> = 1.4) test runner es el siguiente:

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 y DiscoverRunner tienen interfaces principalmente compatibles.

Para obtener más información, debe consultar los documentos "Definición de un corredor de pruebas":

¿Puedo lanzar pruebas para mi aplicación Django reutilizable sin incorporar esta aplicación en un proyecto?

Mi aplicación usa algunos modelos, por lo que es necesario proporcionar la (TEST_)DATABASE_* . ¿Dónde debería almacenarlos y cómo debería lanzar pruebas?

Para un proyecto de Django, puedo ejecutar pruebas con la manage.py test ; cuando uso django-admin.py test con mi aplicación independiente, obtengo:

Error: no se pueden importar configuraciones, porque la variable de entorno DJANGO_SETTINGS_MODULE no está definida.

¿Cuáles son las mejores prácticas aquí?


En un contexto de pytest puro, para proporcionar el entorno Django suficiente para ejecutar pruebas para mi aplicación reutilizable sin un proyecto real de Django, necesitaba las siguientes piezas:

pytest.ini:

[pytest] DJANGO_SETTINGS_MODULE = test_settings python_files = tests.py test_*.py *_tests.py

test_settings.py:

# You may need more or less than what''s shown here - this is a skeleton: DATABASES = { ''default'': { ''ENGINE'': ''django.db.backends.sqlite3'', } } INSTALLED_APPS = ( ''django.contrib.admin'', ''django.contrib.auth'', ''django.contrib.contenttypes'', ''django.contrib.messages'', ''django.contrib.sessions'', ''django.contrib.sites'', ''django.contrib.staticfiles'', ''todo'', ) ROOT_URLCONF = ''base_urls'' TEMPLATES = [ { ''DIRS'': [''path/to/your/templates''), ], } ] MIDDLEWARE = [ ''django.middleware.security.SecurityMiddleware'', ''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'', ]

base_urls.py:

""" This urlconf exists so we can run tests without an actual Django project (Django expects ROOT_URLCONF to exist.) It is not used by installed instances of this app. """ from django.urls import include, path urlpatterns = [ path(''foo/'', include(''myapp.urls'')), ]

templates / base.html:

Si alguna de tus pruebas base.html puntos de vista reales, las plantillas de tu aplicación probablemente extenderán el proyecto base.html , por lo que ese archivo debe existir. En mi caso, acabo de crear un archivo vacío templates/base.html .

Ahora puedo ejecutar pytest -x -v desde mi directorio independiente de aplicaciones reutilizables, sin un proyecto de Django.


Para Django 1.7 es ligeramente diferente. Suponiendo que tiene la siguiente estructura de directorio para la aplicación 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

Así es como el proyecto Django estructura sus pruebas.

Desea ejecutar todas las pruebas en foo/tests/ con el comando:

python3 runtests.py

También desea poder ejecutar el comando desde un directorio principal de tests , por ejemplo, mediante Tox o Invoke, al igual que python3 foo/tests/runtests.py .

La solución que presento aquí es bastante reutilizable, solo se debe ajustar el nombre de la aplicación foo (y aplicaciones adicionales, si es necesario). No se pueden instalar a través de modify_settings , porque se perderá la configuración de la base de datos.

Los siguientes archivos son necesarios:

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)

Algunas de las configuraciones son opcionales; mejoran la velocidad o un entorno más realista.

El segundo argumento apunta al directorio actual. Hace uso de la función de proporcionar una ruta a un directorio para descubrir pruebas debajo de ese directorio .


Para mi aplicación reutilizable ( django-moderation ) utilizo buildout. Creo example_project , lo uso con buildout para ejecutar pruebas en él. Simplemente coloque mi aplicación dentro de la configuración de example_project .

Cuando quiero instalar todas las dependencias usadas por mi proyecto y ejecutar pruebas, solo necesito hacer lo siguiente:

  • Ejecutar: python bootstrap.py
  • Ejecutar buildout:

    bin / buildout

  • Ejecute pruebas para Django 1.1 y Django 1.2:

    bin / test-1.1 bin / test-1.2

Aquí puede encontrar un tutorial sobre cómo configurar la aplicación reutilizable para usar buildout para la implementación y las pruebas ejecutadas: http://jacobian.org/writing/django-apps-with-buildout/

Aquí encontrarás una configuración de buildout de ejemplo que utilizo en mi proyecto:

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


Terminé con esa solución (estaba inspirada en la solución encontrada en django-voting):

Crear archivo, por ejemplo. ''runtests.py'' en el directorio de pruebas que contiene:

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)

Permite ejecutar pruebas mediante el comando python runtests.py . No requiere dependencias instaladas (por ejemplo, buildout) y no daña las pruebas que se ejecutan cuando la aplicación se incorpora al proyecto más grande.