如何启动django可重用应用程序的测试?

dzi*_*ida 45 testing django django-testing

我可以在不将此应用程序合并到项目中的情况下为我的可重用Django应用程序启动测试吗?

我的应用程序使用了一些模型,因此有必要提供(TEST_)DATABASE_*设置.我应该在哪里存储它们以及如何启动测试?

对于Django项目,我可以运行测试manage.py test; 当我使用django-admin.py test我的独立应用程序时,我得到:

错误:无法导入设置,因为未定义环境变量DJANGO_SETTINGS_MODULE.

这里的最佳做法是什么?

ber*_*rni 44

Django(> = 1.4)测试运行器的正确用法如下:

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)
Run Code Online (Sandbox Code Playgroud)

DjangoTestSuiteRunner和DiscoverRunner主要兼容接口.

有关更多信息,请参阅"定义测试运行器"文档:


dzi*_*ida 19

我已经结束了这样的解决方案(它受到django投票中的解决方案的启发):

创建文件,例如.测试目录中的'runtests.py'包含:

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)
Run Code Online (Sandbox Code Playgroud)

它允许按python runtests.py命令运行测试.它不需要安装依赖项(例如buildout),并且当app应用于更大的项目时,它不会损害测试运行.


Iod*_*nas 10

对于Django 1.7来说,它略有不同.假设您有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
Run Code Online (Sandbox Code Playgroud)

这就是Django项目本身如何构建测试的方式.

您希望foo/tests/使用以下命令运行所有测试:

python3 runtests.py
Run Code Online (Sandbox Code Playgroud)

您还希望能够从父目录运行命令tests,例如Tox或Invoke,就像python3 foo/tests/runtests.py.

我在这里提出的解决方案非常可重用,只foo需要调整应用程序的名称(如果需要,还可以调整其他应用程序).它们无法通过modify_settings安装,因为它会错过数据库设置.

需要以下文件:

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 = []
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

有些设置是可选的; 他们提高速度或更现实的环境.

第二个参数指向当前目录.它利用提供目录路径功能来发现该目录下的测试.


Dom*_*opa 5

对于我的可重用应用程序(django-moderation),我使用buildout.我创建example_project,我使用它与buildout运行测试.我只是将我的应用程序放在设置中example_project.

当我想安装我的项目使用的所有依赖项并运行测试时,我只需要执行以下操作:

  • 运行:python bootstrap.py
  • 运行buildout:

    斌/扩建

  • 运行Django 1.1和Django 1.2的测试:

    bin/test-1.1 bin/test-1.2

在这里,您可以找到如何配置可重用应用程序以使用buildout进行部署和测试运行的教程:http://jacobian.org/writing/django-apps-with-buildout/

在这里,您将找到我在项目中使用的示例buildout配置:

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