pytestarch规则验证失败:别名相对导入的模块未被识别
问题排查:pytestarch架构测试断言失败
环境信息
- Linux Mint 21.3(内核
5.15.0-117-generic) - Python 3.10.12
- 使用
pytestarch == 3.0.1
背景
- 项目路径为
/home/developer/python/snakes-and-ladders-engine,目录结构如下:
├── src │ ├── game │ │ └── game.py │ └── utils │ └── gameutilities.py └── tests └── architecture └── test_architecture.py
gameutilities.py仅包含方法,无类定义。game.py通过别名相对导入工具模块:
from ..utils import gameutilities as GameUtilities
- 测试文件中的pytest fixture定义:
@pytest.fixture def game_architecture_instance(project_root: Path, src_root: Path) -> EvaluableArchitecture: return get_evaluable_architecture(str(project_root), str(src_root))
问题描述
我尝试用pytestarch定义规则:gameutilities模块仅允许被game模块导入,测试代码如下:
def test_utilities_invocation_rule(game_architecture_instance: EvaluableArchitecture) -> None: utils_name: str = "snakes-and-ladders-engine.src.utils.gameutilities" game_name: str = "snakes-and-ladders-engine.src.game.game" utilities_invocation_rule: Rule = ( Rule().modules_that() .are_named(utils_name) .should_only().be_imported_by_modules_that() .are_named(game_name) ) utilities_invocation_rule.assert_applies(game_architecture_instance)
执行后触发断言错误:
AssertionError: "snakes-and-ladders-engine.src.utils.gameutilities" is not imported by "snakes-and-ladders-engine.src.game.game".
其他功能测试均正常,仅架构测试失败。请问规则配置哪里出错了?该如何修复?
问题原因及修复方案
核心问题:模块名称匹配逻辑错误
pytestarch识别的模块名称是以src目录为根的相对模块名,而非包含项目根目录全称的路径。你当前使用的snakes-and-ladders-engine.src.utils.gameutilities包含了项目根目录名,这和pytestarch实际解析出的模块名不匹配,导致规则无法识别到已存在的导入关系。
修复步骤
修正模块名称
将测试代码中的模块名改为以src为根的相对格式,或者直接使用src下的层级结构:def test_utilities_invocation_rule(game_architecture_instance: EvaluableArchitecture) -> None: # 去掉项目根目录前缀,使用src起始的模块路径 utils_name: str = "src.utils.gameutilities" game_name: str = "src.game.game" utilities_invocation_rule: Rule = ( Rule().modules_that() .are_named(utils_name) .should_only().be_imported_by_modules_that() .are_named(game_name) ) utilities_invocation_rule.assert_applies(game_architecture_instance)更简洁的写法(因为
src是源码根目录,pytestarch会将其作为模块根):utils_name: str = "utils.gameutilities" game_name: str = "game.game"验证模块名称是否正确
可以先打印pytestarch解析出的所有模块名称,确认匹配逻辑:def test_list_modules(game_architecture_instance: EvaluableArchitecture) -> None: all_modules = game_architecture_instance.modules() for module in all_modules: print(module.name())运行这个测试,就能看到pytestarch实际识别的模块名,再对应修改规则中的名称即可。
确认导入逻辑识别
你使用的相对导入from ..utils import gameutilities as GameUtilities,pytestarch可以正确识别这种导入关系,只要模块名称匹配正确,规则就能正常生效。
内容的提问来源于stack exchange,提问作者Pralines And Cream
相关产品推荐
相关产品推荐

