python - 为什么Behavior 记录的与 Django 的手动集成不起作用?

标签 python django python-2.7 python-behave

我有一个 Django (1.10.2) 项目(“theproject”)和一些行为 (0.4.0) 功能。我一直在使用 django 行为。 python manage.pyBehaviour 有效。然而,PyCharm (which uses the behave executable rather than a Django management command) doesn't know how to run my features ,所以我尝试使用 behave's documented "manual integration" with Django .

我的整个features/environment.py:

import os
import django
from django.test.runner import DiscoverRunner
from django.test.testcases import LiveServerTestCase
from splinter.browser import Browser

os.environ["DJANGO_SETTINGS_MODULE"] = "theproject.settings"

def before_all(context):
    django.setup()
    context.test_runner = DiscoverRunner()
    context.test_runner.setup_test_environment()
    context.old_db_config = context.test_runner.setup_databases()
    context.browser = Browser('phantomjs')

    # When we're running with PhantomJS we need to specify the window size.
    # This is a workaround for an issue where PhantomJS cannot find elements
    # by text - see: https://github.com/angular/protractor/issues/585
    if context.browser.driver_name == 'PhantomJS':
        context.browser.driver.set_window_size(1280, 1024)

def before_scenario(context, _):
    context.test_case = LiveServerTestCase
    context.test_case.setUpClass()

def after_scenario(context, _):
    context.test_case.tearDownClass()
    del context.test_case

def after_all(context):
    context.test_runner.teardown_databases(context.old_db_config)
    context.test_runner.teardown_test_environment()

    context.browser.quit()
    del context.browser

这是来自 theproject/setting.pyINSTALLED_APPS,以防有帮助(我为此实验删除了 'behave-django'):

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_extensions',
    'oauth2_provider',
    'push_notifications',
    'raven.contrib.django.raven_compat',
    'rest_framework',
    'app1.apps.App1Config',
    'app2',
    'django.contrib.admin'  # Must follow apps for apps' models to appear in admin UI
]

当我运行behave时,我得到

Exception AppRegistryNotReady: Apps aren't loaded yet.
Traceback (most recent call last):
  File "/usr/local/bin/behave", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/site-packages/behave/__main__.py", line 109, in main
    failed = runner.run()
  File "/usr/local/lib/python2.7/site-packages/behave/runner.py", line 672, in run
    return self.run_with_paths()
  File "/usr/local/lib/python2.7/site-packages/behave/runner.py", line 678, in run_with_paths
    self.load_step_definitions()
  File "/usr/local/lib/python2.7/site-packages/behave/runner.py", line 658, in load_step_definitions
    exec_file(os.path.join(path, name), step_module_globals)
  File "/usr/local/lib/python2.7/site-packages/behave/runner.py", line 304, in exec_file
    exec(code, globals, locals)
  File "features/steps/common.py", line 5, in <module>
    from django.contrib.auth.models import User
  File "/usr/local/lib/python2.7/site-packages/django/contrib/auth/models.py", line 4, in <module>
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File "/usr/local/lib/python2.7/site-packages/django/contrib/auth/base_user.py", line 52, in <module>
    class AbstractBaseUser(models.Model):
  File "/usr/local/lib/python2.7/site-packages/django/db/models/base.py", line 105, in __new__
    app_config = apps.get_containing_app_config(module)
  File "/usr/local/lib/python2.7/site-packages/django/apps/registry.py", line 237, in get_containing_app_config
    self.check_apps_ready()
  File "/usr/local/lib/python2.7/site-packages/django/apps/registry.py", line 124, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

如何使这种集成 django 和行为的方式发挥作用?

我尝试过的东西不起作用(或不完全):我在设置后将django.setup()移动到environment.py的顶层DJANGO_SETTINGS_MODULE。这修复了 AppRegistryNotReady,但许多情况都会失败

IntegrityError: duplicate key value violates unique constraint "auth_user_username_key"
DETAIL:  Key (username)=(username) already exists.

在behave-django下,事务在每个场景之前启动并在之后回滚;现在看来这种情况不会发生。 LiveServerTestCase 扩展了 TransactionTestCase,所以我很困惑。

最佳答案

您的数据库更改不会在场景之间回滚(因此出现 IntegrityError)。数据库仅在 after_all() 中被拆除。尝试将所有代码移至 before_scenarioafter_scenario 函数中(请参阅 related docs )。

测试的执行时间将会增加,但测试将被隔离。作为一个快速解决方案,这至少让它们暂时通过。在评论和替代答案中提供更清洁解决方案的提示。

关于python - 为什么Behavior 记录的与 Django 的手动集成不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41242766/

相关文章:

python - 如何从 Python 脚本中获取当前的 Python 解释器路径?

python - Cython - 动态二维 C++ 数组的内存 View

python - 具有相同纵横比和单独颜色条的 matplotlib 子图

python - 如何安装 Django 通知?

python - 通过 SSH 运行和安装脚本缺少的模块

Python、字符串、unicode 字符

django - 导入错误: No module named bootstrap3

python - Boto3 在本地和使用 django 应用程序在弹性 beantalk 上生成不同的链接

python - 在 Python 中 pickle 字典

python - 为什么 Anaconda 将我的默认 Python 路径添加到特定环境的路径中?