Flow control and Failed: Database access not allowed, use the "django_db"... 错误
Flow control and Failed: Database access not allowed, use the "django_db".... Error
我 运行 我的一个 celery 任务出现了一些奇怪的行为。
def run_single_test(test_name_or_decorator):
# get dict of test names, test paths
test_dict = get_single_test_names()
# check to see if test is in the dict
if test_name_or_decorator not in test_dict:
return 'The requested test could not be found.'
for test_name, test_path in test_dict.items():
# if test name is valid run associated test
if test_name == test_name_or_decorator:
pytest.main(['-p', 'no:django','--json-report', test_path])
report = return_test_result_json('.report.json')
report_id = str(uuid.uuid4())
test_run_data = TestResults.objects.create(name=report_id, data=report)
return 'this is your test report: {}'.format(get_report(test_run_data.id))
此任务将执行 pytest.main() 命令和 运行 测试,但是当它使用 .create() 将 .report.json 插入 Db 时,我得到了以下错误:
Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.
现在,如果我使用 for test_name....
块中的所有功能来简化事情并将其移动到它自己的函数中,一切正常:
def run_single_test_path():
test_path = 'test_folder/test_file.py::TestClass::specific_test_name'
pytest.main(['-p', 'no:django','--json-report', test_path])
report = return_test_result_json('.report.json')
report_id = str(uuid.uuid4())
test_run_data = TestResults.objects.create(name=report_id, data=report)
return 'this is your test report: {}'.format(get_report(test_run_data.id))
我得到了预期的 return:
"this is your test report: {'created': datetime.datetime(2018, 9, 27, 15, 51, 59, 297991, tzinfo=<UTC>), 'summary': {'total': 1, 'passed': 1}, 'exitcode': 0}"
我的其他使用相同 pytest.main() 和 .create() 变体的任务不会发生此行为。
另一个观察结果是,如果我先 运行 此任务并抛出数据库访问错误,则所有其他任务都将失败并出现相同的错误。
我的工作理论是关于 for 循环或 if 的某些东西导致 .create() 崩溃,但我完全不知道为什么。
一般来说,pytest.main
不关心测试 运行 后留下的全局状态,因为它假定进程在测试 运行 完成后以返回的退出代码终止.因此,如果您在 pytest.main
完成后在同一进程中 运行ning 代码,则必须谨慎对待范围内的修改。其中之一是由 pytest-django
在 django 测试配置中激活的数据库拦截器;它不会在测试执行完成后停用。要停用,请在代码中明确执行:
import pytest_django
def run_single_test(test_name_or_decorator):
...
pytest.main(['-p', 'no:django','--json-report', test_path])
pytest_django.plugin._blocking_manager.unblock()
# database access unblocked, you can run the query now
test_run_data = TestResults.objects.create(name=report_id, data=report)
或添加一个 post-运行 挂钩,它将隐式执行此操作,例如:
# conftest.py
import pytest_django
def pytest_unconfigure(config):
pytest_django.plugin._blocking_manager.unblock()
我 运行 我的一个 celery 任务出现了一些奇怪的行为。
def run_single_test(test_name_or_decorator):
# get dict of test names, test paths
test_dict = get_single_test_names()
# check to see if test is in the dict
if test_name_or_decorator not in test_dict:
return 'The requested test could not be found.'
for test_name, test_path in test_dict.items():
# if test name is valid run associated test
if test_name == test_name_or_decorator:
pytest.main(['-p', 'no:django','--json-report', test_path])
report = return_test_result_json('.report.json')
report_id = str(uuid.uuid4())
test_run_data = TestResults.objects.create(name=report_id, data=report)
return 'this is your test report: {}'.format(get_report(test_run_data.id))
此任务将执行 pytest.main() 命令和 运行 测试,但是当它使用 .create() 将 .report.json 插入 Db 时,我得到了以下错误:
Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.
现在,如果我使用 for test_name....
块中的所有功能来简化事情并将其移动到它自己的函数中,一切正常:
def run_single_test_path():
test_path = 'test_folder/test_file.py::TestClass::specific_test_name'
pytest.main(['-p', 'no:django','--json-report', test_path])
report = return_test_result_json('.report.json')
report_id = str(uuid.uuid4())
test_run_data = TestResults.objects.create(name=report_id, data=report)
return 'this is your test report: {}'.format(get_report(test_run_data.id))
我得到了预期的 return:
"this is your test report: {'created': datetime.datetime(2018, 9, 27, 15, 51, 59, 297991, tzinfo=<UTC>), 'summary': {'total': 1, 'passed': 1}, 'exitcode': 0}"
我的其他使用相同 pytest.main() 和 .create() 变体的任务不会发生此行为。 另一个观察结果是,如果我先 运行 此任务并抛出数据库访问错误,则所有其他任务都将失败并出现相同的错误。
我的工作理论是关于 for 循环或 if 的某些东西导致 .create() 崩溃,但我完全不知道为什么。
一般来说,pytest.main
不关心测试 运行 后留下的全局状态,因为它假定进程在测试 运行 完成后以返回的退出代码终止.因此,如果您在 pytest.main
完成后在同一进程中 运行ning 代码,则必须谨慎对待范围内的修改。其中之一是由 pytest-django
在 django 测试配置中激活的数据库拦截器;它不会在测试执行完成后停用。要停用,请在代码中明确执行:
import pytest_django
def run_single_test(test_name_or_decorator):
...
pytest.main(['-p', 'no:django','--json-report', test_path])
pytest_django.plugin._blocking_manager.unblock()
# database access unblocked, you can run the query now
test_run_data = TestResults.objects.create(name=report_id, data=report)
或添加一个 post-运行 挂钩,它将隐式执行此操作,例如:
# conftest.py
import pytest_django
def pytest_unconfigure(config):
pytest_django.plugin._blocking_manager.unblock()