Управление потоком данных и сбой: доступ к базе данных не разрешен, используйте «django_db» .... Ошибка - PullRequest
0 голосов
/ 28 сентября 2018

У меня странное поведение с одной из моих задач с сельдереем.

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 () и выполнит тест, однако, когда он вставит файл .report.json в БД с помощью .create (), я получаю следующую ошибку:

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))

Я получу ожидаемый доход:

"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 (), но я абсолютно не знаю, почему.

1 Ответ

0 голосов
/ 28 сентября 2018

Как правило, pytest.main не заботится о глобальном состоянии, оставшемся после запуска теста, так как предполагается, что процесс завершается с возвращенным кодом завершения после завершения теста.Таким образом, если вы выполняете код в том же процессе после завершения pytest.main, вы должны быть осторожны с изменениями в области.Одним из них является блокировщик базы данных, активируемый 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)

или добавьте ловушку после запуска, которая будет делать это неявно, например:

# conftest.py

import pytest_django

def pytest_unconfigure(config):
    pytest_django.plugin._blocking_manager.unblock()
...