pytest fixture疑问:为何append_first返回None而非预期列表
pytest fixture返回值为None的原因解析
问题描述
我正在学习pytest,在阅读官方文档中「fixture可在单个测试中多次请求(返回值会被缓存)」的章节时,产生疑问:示例中的断言assert order == [first_entry]能否替换为assert append_first == [first_entry]?实际替换后断言不通过,因为append_first的值为None,但该fixture已执行,我想知道它为何不是['a']。
相关代码
# contents of test_append.py import pytest # Arrange @pytest.fixture def first_entry(): return "a" # Arrange @pytest.fixture def order(): return [] # Act @pytest.fixture def append_first(order, first_entry): return order.append(first_entry) def test_string_only(append_first, order, first_entry): # Assert 1: Pass assert order == [first_entry] # Assert 2: AssertionError: assert None == ['a'] assert append_first == [first_entry]
原因分析
核心问题出在Python的list.append()方法上:
append()是原地修改列表的方法,它只会把元素添加到目标列表中,不会返回修改后的列表,而是固定返回None。- 你的
append_firstfixture里,return order.append(first_entry)实际上返回的是append()方法的执行结果——也就是None,这就是断言失败的直接原因。 - 测试中的
order断言能通过,是因为append_firstfixture执行时,已经依赖并修改了orderfixture实例化的列表(pytest的fixture依赖机制会保证order先被创建,再被append_first修改),所以order变量指向的是已经被修改后的列表对象。
解决方案
如果想让append_first返回修改后的列表,只需要修改fixture,让它返回order本身即可:
@pytest.fixture def append_first(order, first_entry): order.append(first_entry) return order
这样修改后,append_first就会返回添加元素后的列表,断言assert append_first == [first_entry]就能正常通过了。
内容的提问来源于stack exchange,提问作者mab0189
相关产品推荐
相关产品推荐

