

通过自动化单元测试的形式守护系统架构
source link: https://blog.51cto.com/u_15714439/5688939
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

随着需求开发迭代,代码库规模逐渐变大,新的团队成员引入等诸多因素,系统起初制定的架构规则不可避免遭到破坏。不仅仅是破坏团队的统一开发规范,更为重要的是随着代码库规模逐渐增长,大大降低系统的可维护性、扩展性,增加评审复杂度和重构成本,也最终导致团队生产力下降以及研发成本增长。
在敏捷开发环境下,系统通过迭代增量的交付价值,系统架构也是如此。团队不可能在项目之初就建立完美的系统架构,系统架构应该随着系统迭代不断演进。
架构演进和架构腐化是看待架构的不同视角:架构腐化着眼于现状,架构演进侧重于未来
架构腐化不可避免,随着时间流转腐化现象必然发生。而我们需要做的是:通过某种方式及早发现和修正
2 为什么选择Archunit
我们需要通过引入一种机制或技术,降低或及早发现架构腐化现象的发生,保持统一的系统架构约束。
- 支持架构规则自动化检查
- 轻量级,接入成本低
- 结果及时反馈
- 灵活扩展且扩展成本低
对于架构规则常见的验证方式:代码评审、代码质量分析工具或平台、Archunit

以下对常见的几种方式进行优劣势对比:
代码评审:通过强流程控制代码评审活动发生,增强代码评审的强度和质量
优势
- 不需要引入额外的技术,没有学习成本
- 灵活:通过人工评审方式可以覆盖架构约束更全面
劣势
- 非自动化方式执行,质量靠人工保证,人为因素存在较多不可控因素
- 代码评审范围越广,人力成本投入则越大
- 代码评审流程后置,不能及时反馈规则检测结果
代码质量分析工具:比如Sonar、Checkstyle等
优势
- 成熟的工具或平台,内置开箱即用的规则
- 三方工具支持,不影响代码库结构
劣势
- 缺少灵活性,架构规则约束支持程度有限,不能很好的解决架构层面规则约束
- 强调代码质量分析结果,不能有效处理强制规则约束
- 定制规则有一定成本(因平台扩展能力而异)
Archunit:通过单元测试形式对架构规则自动化检查
优势
- 支持丰富的架构约束规则定制能力,例如分层依赖规则、包依赖规则、循环依赖、继承关系约束等
- 虽然以单测代码方式体现,但不影响主业务开发,可以通过增量方式引入,逐步增强应用的架构约束能力
- Archunit 提供的Java 流式API 易于理解,接入和使用成本低
- 使用纯Java单测框架以单元测试形式自动化执行,及时反馈单测结果
劣势
- 需要额外编写单元测试代码,增加了一部分工作量
- 引入了新的类库有一定学习成本
3 Archunit是什么
ArchUnit是一款免费、简单可扩展的类库,它可以使用任何Java单元测试框架来检查Java代码的架构约束。基于Archunit我们可以自动化检测:
- 包的包含关系
- 类的依赖关系
- 类和包的包含关系
Archunit和代码质量分析工具的关系如下图所示,二者都可以对代码进行分析,在功能覆盖上存在一定交叉。

Archunit不能解决所有的架构属性的约束自动化验证,其主要侧重于系统的演进性、可维护性、可测试性、可解释性等,也可以对耦合度、命名规范等进行验证。

4 引入Archunit
4.1 开始就是如此简单
使用Archunit编写架构规则约束非常简单,其提供了便捷的流式API,可以快速的构建规则。
示例1:RULE.01 所有的枚举类必须以Enum为后缀

示例2:对应用分层进行约束校验

在IDE下执行Archiunit单元测试结果示意如下图所示:

4.2 如何组织架构规则
架构规则组织可以从多个维度,比如:
下图左侧所示:基于逻辑分类对规则进行分组
下图右侧所示:基于职能分类对规则进行分组

4.3 团队如何规范化
团队是否要引入Archunit本身也是一项架构决策,建议采用文档化形式对该决策进行记录,记录形式参考 《 轻量级架构决策记录机制 》
如果团队想要引入Archunit,从流程化和规范化视角可以基于准备-试点-优化-推广的模式进行实施:

实施准备:
- 从规范复用的角度考虑,团队需要定义统一的开发规范,包括但不限于编码规范、异常规范、命名规范、依赖规范等等,并在团队内达成一致。建议采用统一的、文档化的形式进行记录(比如,在线表格系统)。对于每条开发规则建议增加比如 “正例”、“反例”、“规则描述”、“规则详细说明”、“是否可自动实现” 等维度描述信息
- 基于Archunit实现通用架构约束以便在不同项目间进行复用
应用试点:在产品线内部选定一个试点应用
复盘优化:基于试点效果进行复盘,基于团队成员反馈进行架构规则优化、已有规则的修改及废弃等等
推广普及:基于试点的一些实践在其它应用或业务线进行推广普及
对于遗留系统已经形成了特定的规则(有可能是已经发生腐化),由于业务系统的持续迭代,在单个迭代完全大规模重构已有系统的可能性不大。所以,建议采增量方式,在迭代研发资源可接受的范围内,逐步引入并丰富架构规则,并对破坏规则的应用代码进行重构。
Archunit不能做什么:
- 测试所有架构属性
- 只支持JVM语言
- SOURCE注解
- 需要导入大量代码,加入CICD流水线后的时长影响
- 不能保证自身的维护性
Archunit对架构约束的自动化检测极有价值,且具有较低的接入和定制化成本,强烈建议团队引入试点。引入Archunit进行架构约束自动化检查后,将对以下方面产生影响:
- 有助于降低系统架构腐化,提升系统可维护性
- 新类库引入有一定的学习成本
- 代码评审活动增加一项活动:执行架构约束单元测试
- 开发成员日常开发中需要持续执行并关注架构约束单测结果,并确保测试通过
Recommend
-
30
1)如何通过Timeline的形式实现技能编辑器 2)Addressable如何通过Group Name获得Group下的Key 3)Unity如何获取Sprite在Sprite Packer中的UV值 4)AnimatorController在UnityEditor下,如何获取所有的状态名 5)Unity为UGUI的Mask做...
-
10
参杂译者吐槽的正文 一、得了开头不吐槽不舒服的病 我昨晚非一人去看《北京备胎西雅图》了,还不错哦~
-
11
数据中心如何作为计算单元使其自动化开放网络 责任编辑:cres 作者:Ami Badani | 2021-03-15 13:40:19 原创文章 企业网D1Net 数据中心已经从物理服务器发展到虚拟化系统,现在发展到可组合的...
-
9
Autofac 通过 PreserveExistingDefaults 解决单元测试 Fake 对象被覆盖在使用 Autofac 作为 IoC 容器,因为 Autofac 默认的创建时机是在主机运行时。而在此 Module 被 Load 时注入的对象的注入的时机,将会在单元测试 Fake 注入之后,这就意味着 Load 时注...
-
7
Posted by: Phodal Huang June 15, 2021, 8:33 p.m. 架构守护代码化,即使用易于阅读和维护的领域特定语言,来描述软件架构守护的规则,对诸如于分层架构、包访问规则、包数量、...
-
5
200 万元!“苏周到”通过答题抽奖形式发放公交出行数字人民币红包10 月 9 日讯,苏州官方城市生活服务 App“苏周到”将于下周面向参与常态化疫情防控有奖答题的用户赠送数字人民币红包,总额高达 200 万元。据悉,单个奖品为价值 20 元的农业银行数...
-
4
原创发布于 tech.glowing.com。 接着...
-
5
pytest测试框架也是主流的一个测试框架,推荐使用该框架,对比unnitest框架来说,其效率更高 1.Pytest介绍 pytest测试框架也是主流的一个测试框架,推荐使用该框架,对比unnitest框...
-
8
Selenium3自动化测试【39】单元测试Pytest(2) 原创 pytest测试框...
-
8
C/C++ 单元自动化测试解决方案实践
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK