Требуется параметризованная метка django_db в Pytest

Я пишу модульные тесты для функции. В parameterize я генерирую тесты, делая некоторые вызовы БД, когда это необходимо.

def my_function(tokens):
    pass

def generate_tokens_helper():
    tokens = list(MyTable.objects.values())
    return tokens

@pytest.mark.django_db
class TestMyClass:

    @pytest.mark.parameterize(
        "tokens, expected_result",
        [
            (
                generate_tokens_helper(),
                True
            )
        ],
    )
    def test_my_function(self, tokens, expected_result):
        assert expected_result == my_function(tokens)

При этом возникает следующая ошибка:

test_file.py:47: in <module>
    class TestMyClass:
test_file.py:17: in TestMyClass
    generate_token_helper(),
test_file.py:5: in generate_token_helper
    items = list(MyTable.objects.values())
spm/accessors/variable_accessor.py:182: in get_all_operators
    operator_list = list(qs)
venv/lib/python3.9/site-packages/django/db/models/query.py:269: in __len__
    self._fetch_all()
venv/lib/python3.9/site-packages/django/db/models/query.py:1308: in _fetch_all
    self._result_cache = list(self._iterable_class(self))
venv/lib/python3.9/site-packages/django/db/models/query.py:53: in __iter__
    results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
venv/lib/python3.9/site-packages/django/db/models/sql/compiler.py:1154: in execute_sql
    cursor = self.connection.cursor()
venv/lib/python3.9/site-packages/django/utils/asyncio.py:26: in inner
    return func(*args, **kwargs)
venv/lib/python3.9/site-packages/django/db/backends/base/base.py:259: in cursor
    return self._cursor()
venv/lib/python3.9/site-packages/django/db/backends/base/base.py:235: in _cursor
    self.ensure_connection()
E   RuntimeError: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it.

Я уже отметил TestMyClass с django_db, но я все еще получаю эту ошибку.

Я смог решить эту проблему, используя следующее:

  • Я написал функцию fixture generate_tests_for_my_function которая будет выполнять необходимые вызовы БД для генерации входных данных для модульного теста.
  • Затем я использовал это приспособление для прямой параметризации в test_my_function.

Итак, приспособление сначала оценивается, что генерирует тестовые входы. Затем эти тестовые входы передаются в функцию тестирования.

@pytest.fixture
def generate_tests_for_my_function(request):
    """Returns a tuple of (tokens, expected_result) as per the test_id"""
    test_id = request.param
    if test_id == 0:
        return (generate_tokens_helper(), True)
    elif test_id == 1:
        return (generate_tokens_helper(), True)


@pytest.mark.django_db
class TestMyClass:
    @pytest.mark.parameterize("generate_tests_for_my_function", [0, 1], indirect=True)
    def test_my_function(self, generate_tests_for_my_function):
        tokens, expected_result = generate_tests_for_my_function
        assert expected_result == my_function(tokens)

Это все еще немного утомительно, поскольку я должен добавить новый идентификатор теста и новое if условие, если я хочу добавить новые тесты. Пожалуйста, прокомментируйте, можно ли это улучшить.

Вернуться на верх