Требуется параметризованная метка 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
условие, если я хочу добавить новые тесты. Пожалуйста, прокомментируйте, можно ли это улучшить.