使用pytest测试自定义BackPath类排序时遇AttributeError求助
问题排查与修复
核心错误原因
- Fixture未正确注入:你直接在测试函数里用
list_of_paths,但它是pytest fixture函数,不是实际的列表对象,必须把它作为测试函数的参数传入,pytest才会自动执行fixture并返回实例。同理,list_of_paths内部引用的path22等也是fixture,需要注入到list_of_paths中。 - sort方法的返回值陷阱:
list.sort()是原地修改列表,执行后返回None,不能直接和预期列表做相等判断,得用sorted()生成新的排序后列表,或者先复制原列表再排序后对比。
修复后的完整代码
from pathlib import Path import pytest class BackPath: def __init__(self, path_name: str): self.full_name = path_name self.path = Path(path_name) self.parts = self.path.parts self.back = list(self.parts[::-1]) self.name = self.back[0] def __gt__(self, other): return self.back > other.back # 补充完整比较运算符,保证排序逻辑正常运行 def __lt__(self, other): return self.back < other.back def __eq__(self, other): return self.back == other.back def __ge__(self, other): return self.back >= other.back def __le__(self, other): return self.back <= other.back def __ne__(self, other): return self.back != other.back @pytest.fixture def path11(): """Return .../dir1/file1.test.""" return BackPath("C:/Users/Steve/PycharmProjects/ImageProcessing/data/dir1/file1.txt") @pytest.fixture def path12(): return BackPath("C:/Users/Steve/PycharmProjects/ImageProcessing/data/dir1/file2.txt") @pytest.fixture def path21(): return BackPath("C:/Users/Steve/PycharmProjects/ImageProcessing/data/dir2/file1.txt") @pytest.fixture def path22(): return BackPath("C:/Users/Steve/PycharmProjects/ImageProcessing/data/dir2/file2.txt") @pytest.fixture def list_of_paths(path22, path12, path21, path11): """list(path22, path12, path21, path11).""" return [path22, path12, path21, path11] def test_sort_works(list_of_paths, path11, path21, path12, path22): # 测试按full_name排序 sorted_by_fullname = sorted(list_of_paths, key=lambda x: x.full_name) assert sorted_by_fullname == [path11, path21, path12, path22] # 测试自定义比较运算符的排序(按文件名优先,目录层级从低到高) sorted_by_custom = sorted(list_of_paths) # 按back字段排序的预期顺序:同文件名先比目录层级(dir1 < dir2),再按文件名排序 assert sorted_by_custom == [path11, path21, path12, path22]
关键修复点说明
- Fixture注入规则:所有需要使用的fixture都要作为参数传入对应的函数(测试函数或其他fixture),pytest会自动处理依赖,返回实例而非函数对象。
- 排序方法选择:用
sorted()替代list.sort(),前者返回排序后的新列表,适合直接做断言对比;如果非要用sort(),需要先复制原列表:temp_list = list_of_paths.copy() temp_list.sort(key=lambda x: x.full_name) assert temp_list == [path11, path21, path12, path22] - 补充完整比较运算符:仅实现
__gt__不足以支撑完整排序逻辑,必须补充__lt__、__eq__等方法,确保Python的排序算法能正常工作。
内容的提问来源于stack exchange,提问作者Steve Maguire
相关产品推荐
相关产品推荐

