我建立了一个 Django 网站以及基于 pytest 和 pytest-django 包的测试。我希望获得 PyMySQL 包以配合我的测试和生产设置。
我知道为了让 PyMySQL 将自己暴露为 mysqldb 模块以便 django(和其他模块)可以使用它 我应该将以下代码片段放在代码的开头。
import pymysql
pymysql.install_as_MySQLdb()
我多次尝试在我的代码中的不同位置调用上述函数,但 pytest 似乎没有足够早地检测到。
这包括将代码片段放在 conftest.py:pytest_configure 中,放在我的 django 项目的 manage.py 文件中,等等。都没有用。
我从 mysqlclient 切换到 PyMySQL 的原因是 mysqlclient 在我使用 travis.org 后似乎无法正常工作在 .travis.yml 中包含以下内容:
addons:
mariadb: '10.0'
为了使用 MariaDB 而不是 vanilla MySQL。
让 travis 与 python mysqlclient 包一起工作也将解决我的问题,但我也无法完成。
供引用,this是 PR 的 travis 工作,以防我错过一些重要的事情。
请您参考如下方法:
好吧,起初我认为这是不可能的,因为 pytest-django 已经在模块级别导入了很多 django 的东西,你无法通过通过钩子(Hook)插入你自己 - 它们都是在插件通过入口点加载后执行的,因此 django 届时将已经导入。
但是,查看 pytest --help,注意一个很少使用的选项,它在这种情况下很有用:
$ pytest --help
...
test session debugging and configuration:
-p name early-load given plugin (multi-allowed). To avoid
loading of plugins, use the `no:` prefix, e.g.
`no:doctest`.
通过插件早期加载运行pymysql配置
因此通过 -p arg 传递的自定义插件将比通过入口点加载的插件更早导入。解决方案现在很简单:编写一个导入和配置 pymysql 的小模块,并通过 -p arg 传递它:
# rematch/pymysql_hack.py
import pymysql
pymysql.install_as_MySQLdb()
测试调用:
$ PYTHONPATH=. pytest -p pymysql_hack -rapP server tests/server
我 fork 了 rematch 项目来测试它,the jobs are looking good (第一个作业失败是因为我懒得在所有需求文件中添加pymysql)。
放弃pytest,使用manage.py test
或者(这是我的第一个解决方案建议),您可以通过 manage.py 运行测试,因此您可以在 之上添加 ,实现自定义测试运行器,如 pymysql 配置行manage.pypytest-django's FAQ 中所述:
pytest-django is designed to work with the
pytestcommand, but if you really need integration withmanage.py test, you can create a simple test runner like this:class PytestTestRunner(object): """Runs pytest to discover and run tests.""" def __init__(self, verbosity=1, failfast=False, keepdb=False, **kwargs): self.verbosity = verbosity self.failfast = failfast self.keepdb = keepdb def run_tests(self, test_labels): """Run pytest and return the exitcode. It translates some of Django's test command option to pytest's. """ import pytest argv = [] if self.verbosity == 0: argv.append('--quiet') if self.verbosity == 2: argv.append('--verbose') if self.verbosity == 3: argv.append('-vv') if self.failfast: argv.append('--exitfirst') if self.keepdb: argv.append('--reuse-db') argv.extend(test_labels) return pytest.main(argv)Add the path to this class in your Django settings:
TEST_RUNNER = 'my_project.runner.PytestTestRunner'
并通过
调用测试$ python manage.py test <django args> -- <pytest args>
但是,您将无法使用此解决方案通过直接调用 pytest 来运行测试。
