20
Iβve ended with such solution (it was inspired by solution found in django-voting):
Create file eg. βruntests.pyβ in tests dir containing:
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)
It allows to run tests by python runtests.py
command.
It doesnβt require installed dependencies (eg. buildout) and it doesnβt harm tests run when app is incorporated into bigger project.
45
The correct usage of Django (>= 1.4) test runner is as follows:
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 and DiscoverRunner have mostly compatible interfaces.
For more information you should consult the βDefining a Test Runnerβ docs:
- DjangoTestSuiteRunner (Django >=1.4, <1.8)
- DiscoverRunner (Django >=1.8)
- [Django]-In Django is there a way to display choices as checkboxes?
- [Django]-Django Admin Form for Many to many relationship
- [Django]-Django: Record with max element
10
For Django 1.7 itβs slightly different. Assuming you have the following
directory structure for app 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
This is how the Django project itself structures its tests.
You want to run all tests in foo/tests/
with the command:
python3 runtests.py
You also want to be able to run the command from a parent directory of tests
, e.g. by Tox or Invoke, just like python3 foo/tests/runtests.py
.
The solution I present here is quite reusable, only the appβs name foo
must be adjusted (and additional apps, if necessary). They can not be installed via modify_settings, because it would miss the database setup.
The following files are needed:
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)
Some of the settings are optional; they improve speed or a more realistic environment.
The second argument points to the current directory. It makes use of the feature of providing a path to a directory to discover tests below that directory.
- [Django]-Django-cors-headers not work
- [Django]-Coercing to Unicode: need string or buffer, NoneType found when rendering in django admin
- [Django]-Pypi see older versions of package
5
For my reusable app(django-moderation) I use buildout. I create example_project
, i use it with buildout to run tests on it. I simply put my app inside of settings of example_project
.
When i want to install all dependencies used by my project and run tests, i only need to do following:
- Run: python bootstrap.py
-
Run buildout:
bin/buildout
-
Run tests for Django 1.1 and Django 1.2:
bin/test-1.1
bin/test-1.2
Here you can find tutorial how to configure reusable app to use buildout for deployment and tests run: http://jacobian.org/writing/django-apps-with-buildout/
Here you will find example buildout config which i use in my project:
http://github.com/dominno/django-moderation/blob/master//buildout.cfg
- [Django]-Using Cloudfront with Django S3Boto
- [Django]-Django: using blocks in included templates
- [Django]-Django py.test does not find settings module
3
In a pure pytest context, to provide just enough Django environment to get tests running for my reusable app without an actual Django project, I needed the following pieces:
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:
If any of your tests hit actual views, your appβs templates will probably be extending the project base.html
, so that file must exist. In my case, I just created an empty file templates/base.html
.
I can now run pytest -x -v
from my standalone reusable app directory, without a Django project.
- [Django]-Django β Clean permission table
- [Django]-Connect to a DB using psycopg2 without password
- [Django]-How can I set two primary key fields for my models in Django?
0
I know this is an old thread, but I have found that if your reusable app has a file βtests.pyβ, then you can create a tests.py inside your project folder, and then write the followingβ¦
from reusableapp.tests import *
Django will then run these tests when you call βpython manage.py testβ
- [Django]-DatabaseError: value too long for type character varying(100)
- [Django]-Profiling Django
- [Django]-How to register users in Django REST framework?