☰
如何用ArchUnitPython声明Clean Architecture与分层依赖:project_layers()实战教程
2026/11/5 3:42:00 网站建设 项目流程

【免费下载链接】ArchUnitPython

ArchUnitPython is an architecture testing library. Specify and ensure architecture rules in your Python app. Easy setup and pipeline integration.

项目地址:https://gitcode.com/gh_mirrors/ar/ArchUnitPython
点击查看免费下载

ArchUnitPython 是一款 Python 架构测试(Architecture Testing)库,本教程带你用project_layers()快速声明 Clean Architecture 与分层依赖规则,把"高层不能依赖底层"这类架构约束变成 CI 里自动运行的测试。

为什么需要架构测试?

代码评审能拦住一部分"controllers 直接 new 了一个数据库连接"的坏味道,但拦不住下一次。把架构规则写成可执行的测试后:

  • ✅ 规则常驻在测试套件里,每次提交自动校验
  • ✅ 违规时直接输出具体是哪条文件依赖,定位飞快
  • ✅ 架构决策被"版本化"进代码库,新人一看测试就懂设计意图

ArchUnitPython 零运行时依赖(纯标准库),pip install archunitpython即装即用,兼容 pytest、unittest 及任何测试框架。

先认识示例项目的分层结构

下面所有例子基于这样的项目布局(顶层包放在src/下):

目录层名职责
src/presentation/表现层控制器、API 路由
src/business/业务层领域逻辑
src/database/数据层持久化、ORM 访问

Clean Architecture 的核心约束很直白:依赖只能向内指向—— presentation → business → database,反向依赖一律不允许。

仓库自带的示例工程同样遵循三层结构,可对照阅读:

  • controller.py:控制器只依赖 services
  • service.py:服务只依赖 models
  • model.py:模型层零内部依赖

三步用 project_layers() 声明分层依赖

第一步:用 .layer() 命名你的层

project_layers()接收导入根目录(import root,即包含顶层包的目录),随后用链式调用为每一层命名。层可以用defined_by_folder()按文件夹 glob 模式定义,也可以用defined_by()按完整路径模式定义:

from archunitpython import project_layers rule = ( project_layers("src/") .layer("presentation").defined_by_folder("**/presentation/**") .layer("business").defined_by_folder("**/business/**") .layer("database").defined_by_folder("**/database/**") )

💡**可跨多级目录匹配,所以无论层嵌套多深都能命中。

第二步:用 where_layer() 声明允许谁依赖谁

命名完层后,用where_layer()进入某一层的依赖规则配置。白名单语义由may_only_depend_on_layers()表达——括号里没列出的层,一律视为违规:

.where_layer("presentation") .may_only_depend_on_layers("business") .where_layer("business") .may_only_depend_on_layers("database") .where_layer("database") .may_only_depend_on_layers() # 数据层:不允许依赖任何已命名层

最后那个空参数的may_only_depend_on_layers()值得注意:底层不允许再向外依赖任何层,这正是 Clean Architecture 的"依赖指向内部"原则。

第三步:交给断言,跑起来

完整规则配上assert_passes(),就是一个标准的 pytest 用例:

from archunitpython import assert_passes, project_layers def test_clean_architecture_layers(): rule = ( project_layers("src/") .layer("presentation").defined_by_folder("**/presentation/**") .layer("business").defined_by_folder("**/business/**") .layer("database").defined_by_folder("**/database/**") .where_layer("presentation") .may_only_depend_on_layers("business") .where_layer("business") .may_only_depend_on_layers("database") .where_layer("database") .may_only_depend_on_layers() ) assert_passes(rule)

测试通过即代表全项目符合分层依赖规则;任何人在错误的层里加了一行 import,CI 立刻红给你看。

白名单还是黑名单?两种规则语义

where_layer()之后有两个可选动作,语义正好相反:

方法语义适用场景
may_only_depend_on_layers(a, b)白名单:只允许依赖列出的层架构收敛、想"锁死"依赖方向
may_not_depend_on_layers(a)黑名单:仅禁止依赖列出的层只针对个别违规做精准封堵

两者也可在同一个规则里叠加使用。判断逻辑的完整实现见 layer_dependencies.py,规则构建器 API 则定义在 layers.py。

违规了会看到什么?

断言失败时,assert_passes()会输出编号清晰的违规清单,直接给出层名 + 具体文件,例如:

Found 1 architecture violation(s): 1. Layer dependency violation Layer 'presentation' depends on disallowed layer 'database' via 'src/presentation/handler.py' -> 'src/database/repository.py'

输出格式化逻辑在 assertion.py 和 violation_factory.py,违规类型LayerDependencyViolation携带源层、目标层和那条具体的依赖边,修复起来不用猜。

还可以顺手用.because(...)给规则补一句"为什么",失败信息里会一并展示,方便后来的同事理解规则意图。

新手最容易踩的 3 个坑

  1. 导入根目录传错。project_layers("src/")里的参数要指向包含顶层包的目录:包在src/taskboard/就传"src",包就在仓库根目录就传"."。根目录选错会导致内部 import 被误判为外部依赖,层规则悄悄漏检。
  2. glob 模式不命中时先自查。defined_by_folder("**/business/**")写错路径会静默匹配不到文件,建议先用调试日志(CheckOptions的 logging 选项)确认层确实圈到了文件。
  3. 同层依赖不检查。两条边若起止于同一个层,规则直接跳过(见 layer_dependencies.py),层内循环依赖请搭配have_no_cycles()规则一起使用。

规则写法与真实运行示例可参考官方测试套件 test_layers.py,它对通过、白名单违规、黑名单违规三种场景都有覆盖。

小结

用project_layers()声明 Clean Architecture 的完整套路就是三步:

  1. layer("x").defined_by_folder(...)—— 给层命名
  2. where_layer("x").may_only_depend_on_layers(...)—— 定依赖方向
  3. assert_passes(rule)—— 让 CI 替你守门

一条规则十几行代码,换回整个团队对架构的持续保证。更多架构测试玩法(循环依赖检测、代码指标、UML 图校验等)可以翻一下项目根目录的 README.md,它涵盖了全部使用场景。

【免费下载链接】ArchUnitPython

ArchUnitPython is an architecture testing library. Specify and ensure architecture rules in your Python app. Easy setup and pipeline integration.

项目地址:https://gitcode.com/gh_mirrors/ar/ArchUnitPython
点击查看免费下载
上一篇:openai-cpa安全最佳实践:密钥管理与访问控制避坑指南
下一篇:该选哪个 AI Skill?yao-open-skills 15 大能力场景选型完全指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询