已标记django_db仍报错:参数化测试中数据库访问被禁止
问题原因
你遇到的问题核心是:测试用例的参数化列表在类加载阶段就会被求值,而非等到测试方法执行时。你在@pytest.mark.parameterize里直接调用generate_tokens_helper(),这行代码会在TestMyClass类被定义的时候就执行——此时@pytest.mark.django_db标记还没生效,数据库连接未被允许,所以触发了数据库访问错误。
解决方法
下面提供两种可行的修复方案:
方案一:在测试方法内部生成测试数据
把过滤条件作为参数传递,在测试方法内部调用数据库查询方法,此时已经处于django_db标记的上下文环境中,数据库访问是合法的:
def my_function(tokens): pass def generate_tokens_helper(**filters): tokens = list(MyTable.objects.values(**filters)) return tokens @pytest.mark.django_db class TestMyClass: @pytest.mark.parametrize( "filters, expected_result", [ ({}, True), # 空过滤条件,查询所有数据 # 可添加更多过滤组合,比如{"status": "active"}, True ], ) def test_my_function(self, filters, expected_result): # 测试方法内调用helper,此时数据库访问已被允许 tokens = generate_tokens_helper(**filters) assert expected_result == my_function(tokens)
方案二:使用Fixture延迟生成测试数据
通过pytest的fixture机制,让测试数据在测试执行阶段才生成,配合indirect=True实现参数化的间接调用:
import pytest from myapp.models import MyTable def my_function(tokens): pass # 将helper改成fixture,接收request参数获取传入的过滤条件 @pytest.fixture def generate_tokens_helper(request): filters = request.param if request.param else {} return list(MyTable.objects.values(**filters)) @pytest.mark.django_db class TestMyClass: @pytest.mark.parametrize( "generate_tokens_helper, expected_result", [ ({}, True), # 传入过滤条件,由fixture处理 ], # 标记该参数为fixture,延迟到测试执行时调用 indirect=["generate_tokens_helper"] ) def test_my_function(self, generate_tokens_helper, expected_result): assert expected_result == my_function(generate_tokens_helper)
内容的提问来源于stack exchange,提问作者Sreekar Mouli
相关产品推荐
相关产品推荐

