pytest中autouse=True未生效?first_entry为何仍为'a'而非['a']
pytest autouse fixture 疑问解答
问题代码
import pytest @pytest.fixture def first_entry(): return "a" @pytest.fixture(autouse=True) def append_first(first_entry): return [first_entry] def test_string_only(first_entry): assert first_entry == ["a"]
以上代码修改自pytest官方示例,运行后测试失败,错误日志如下:
======================================================= FAILURES ======================================================== ___________________________________________________ test_string_only ____________________________________________________ first_entry = 'a' def test_string_only(first_entry): > assert first_entry == ["a"] E AssertionError: assert 'a' == ['a'] test_fixture2.py:24: AssertionError
问题核心
明明设置了autouse=True的append_first会自动执行,为什么测试用例里的first_entry还是字符串"a",不是append_first返回的列表["a"]?
原因分析
autouse=True的fixture确实会在每个测试用例执行前自动运行,但它不会修改其他fixture的返回值:
first_entryfixture的定义就是返回字符串"a",当测试用例显式请求first_entry时,pytest会直接调用这个fixture获取结果,和append_first完全无关。append_first虽然自动运行了,但它的返回值没有被任何测试用例或其他fixture接收,相当于白执行了,不会对first_entry产生任何影响。
解决方法
如果想让测试用例拿到列表形式的结果,可以选以下两种方式:
- 直接修改原fixture:
@pytest.fixture def first_entry(): return ["a"]
- 定义新fixture并在测试中主动请求:
import pytest @pytest.fixture def first_entry(): return "a" @pytest.fixture def wrapped_first_entry(first_entry): return [first_entry] def test_string_only(wrapped_first_entry): assert wrapped_first_entry == ["a"]
另外补充:autouse fixture的设计初衷是处理有副作用的操作,比如初始化数据库、设置环境变量、清理临时文件等,而非用来改变其他fixture的返回值。
内容的提问来源于stack exchange,提问作者ordem
相关产品推荐
相关产品推荐

