【JUnit实战3_11】第六章:关于测试的质量(下) - 详解

news/2025/11/19 11:19:02/文章来源:https://www.cnblogs.com/yangykaifa/p/19241565

JUnit in Action, Third Edition

《JUnit in Action》全新第3版封面截图

写在前面
都说开卷有益,这一章给我的感受颇深。关于作者提到的每一个基本原则,建议大家结合之前工作中的相关场景进行理解,会有不一样的体会。本章最后提到的变异测试虽然没有过多展开,但通过自行查阅相关资料,也解决了之前困扰我很久的一个问题:测试用例用于验证代码逻辑是否正确,但用例本身的质量又通过什么来衡量呢?这就是变异测试试图回答的终极命题,也让我对测试这一领域更加心存敬畏。和我一起来一探究竟吧。

第六章 测试质量(下)

(接上篇)

原则三:构造函数要尽量简单

(详见 上篇笔记)


原则四:遵循 Demeter 法则(最少知识原则)

一个类应当仅了解它必须知道的内容。

其他常见表述:

  • Talk to your immediate friends.
  • Don’t talk to strangers.
// before
class Car {
private Driver driver;
Car(Context context) {
this.driver = context.getDriver();
}
}
// after
Car(Driver driver) {
this.driver = driver;
}

切记:

直接限定对象,而不是中转搜寻对象;只获取程序必需的对象(引入 context 就是个反例)。

小知识:Miško Hevery 社会化类比

将类之间的关系比作社交关系,提倡类之间应该像社交场景下的独立个体一样,保持 清晰的边界最小化依赖

要点提炼:

  • 明确职责边界:每个类应该像社会中的个人一样,有自己明确的职责和能力范围
  • 最小化社交圈:类之间的依赖关系要尽可能少,就像一个人不需要认识全社会的人也能正常工作
  • 自给自足:类应该尽可能独立完成自己的任务,而不是过度依赖其他类
  • 契约化协作:类之间通过清晰的接口(契约)进行协作,而不是紧密耦合

换言之,A 与 B 相熟,但与 C 都不熟,那么 C 就不应该知道 AB 之间共享的信息。这是最理想的情况。但如果 A 刻意隐瞒与 C 也认识,那么这种平衡就会打破,关键信息就可能在看不见的隐秘途径间传递,从而加大测试难度。

原则五:避免隐藏依赖和全局状态

// before
public void makeReservation() {
Reservation reservation = new Reservation();
reservation.makeReservation();
}
public class Reservation {
public void makeReservation() {
manager.initDatabase(); //manager is a reference to a global
//DBManager, already initialized
//require the global DBManager to do more action
}
}
// after
public void makeReservation() {
DBManager manager = new DBManager();
manager.initDatabase();
Reservation reservation = new Reservation(manager);
reservation.makeReservation();
}

切记:引入全局变量时并非仅仅引入该变量本身,也包括与它存在依赖关系的 所有业务逻辑

原则六:优先考虑泛型方法

在最为核心的底层业务逻辑中,如果大量使用通用的静态方法,会给测试造成极大干扰,导致大量的测试冗余代码,也不利于测试逻辑的植入。

相比于静态方法,更推荐的做法是利用 OOP 的多态特性,为后续测试提供更多的 接合点/连接点(articulation points,即多采用 父类接口 + 子类实现 的多态设计构建各功能模块。这样一来,后续测试只需要创建一个针对测试的子类实现就能轻松替换原逻辑,具备更好的可扩展性和可维护性。

相比之下,静态方法的灵活性就差了很多,因为缺乏有效的连接点,不得不在测试用例中大量重复调用静态方法,也无法灵活切换到测试场景下。

// before
public static Set union(Set s1, Set s2) {
Set result = new HashSet(s1);
result.addAll(s2);
return result;
}
// after
public static <E> Set<E> union(Set<E> s1, Set<E> s2) {Set<E> result = new HashSet<>(s1);result.addAll(s2);return result;}

原则七:优先考虑组合而非继承

继承仅在满足 IS-A 关联关系时考虑使用。

最佳实践:应当尽量让代码在运行时保持最大的灵活性。
这样就能确保对象状态之间的切换变得容易,从而使代码更易于测试。

令人感到讽刺的是,Java 的内部库也存在违反这一原则的情况:

  • Stack 继承了 Vector:按理 Stack 又不是 VectorIS-A 不成立),不该继承;
  • Properties 继承了 Hashtable:同上,IS-A 关系也不成立,也不该继承。

原则八:优先使用多态而非条件判断

直接上代码:

// before
public class DocumentPrinter {
// snip
public void printDocument() {
switch (document.getDocumentType()) {
case WORD_DOCUMENT:
printWORDDocument();
break;
case PDF_DOCUMENT:
printPDFDocument();
break;
case TEXT_DOCUMENT:
printTextDocument();
break;
default:
printBinaryDocument();
break;
}
}
// snip
}
// after:
public class DocumentPrinter {
// snip
public void printDocument(Document document) {
document.printDocument();
}
}
public abstract class Document {
// snip
public abstract void printDocument();
}
public class WordDocument extends Document{
// snip
public void printDocument() {
printWORDDocument();
}
}
public class PDFDocument extends Document {
// snip
public void printDocument() {
printPDFDocument();
}
}
public class TextDocument extends Document {
// snip
public void printDocument() {
printTextDocument();
}
}

6.5 测试驱动开发简介

概念:测试驱动开发(TDD 是这样一种编程实践:它强调 测试先行,然后编写代码以通过这些测试;接着审查代码并 适当重构,以进一步改进设计。

TDD 旨在产出 可胜任工作的整洁代码

TDD 让测试用例成为待测方法的 第一位用户,与传统的流程(先编写待测方法,然后再测试验证该方法)不同。

传统开发流程:

[code, test, (repeat)]

TDD 开发流程:

[test, code, (repeat)]

现实中的真实流程还应加入 重构

[test, code, _refactor_, (repeat)]

TDD 两步法:

  • 编写新代码之前先编写一个失败的测试;
  • 编写能让失败测试通过的最少量代码。

6.6 JUnit 最佳实践

先编写未通过的测试(Write failing tests first

初始的未通过状态,表明此时还没有正确实现既定的业务逻辑。一旦养成习惯,开发新模块时就会先写测试再写功能模块,然后重构、优化。该过程熟练后,测试通过的时候,往往也是该模块大功告成的时候。

6.7 行为驱动开发简介

概念:行为驱动开发(Behavior-driven Testing 是这样一种开发手段:它强调 直接满足业务需求,其核心理念是由业务战略、需求和目标驱动,并将这些因素提炼、转化为最终的 IT 解决方案。

BDD 旨在构建值得构建的软件,并以解决用户痛点为己任。

软件的商业价值究竟体现在什么地方?
BDD 给出的回答是:体现在能够胜任实际工作的 功能特性(features 上。功能特性 是可交付、有形的碎片化功能,可有效帮助相关业务达成商业目的。

为实现业务目标——

这些叙事逻辑需要用具体的测试用例进行描述,并最终转化为用户叙事的验收标准。

BDD 固定句式:

6.8 变异测试简介

100% 的代码覆盖率并不意味着你的代码就完美无瑕了——测试代码可能还不够好。

最极端的情况:在测试中略过所有断言。
例如,输出结果过于复杂难以验证,只能将其打印或写入日志,让其他人来决定怎么处理。

变异测试(Mutation testing:又称 变异分析(mutation analysis程序变异(program mutation,主要用于设计新的软件测试、评估现有软件测试的质量。

变异测试的目的在于 检验测试质量,并确保测试符合预期

基本原理:对程序 P 进行细微修改。每个修改后的版本 M 称为 P变体(mutantP 则是 M父体(parent;原始版本的行为与变异体不同,测试执行需要检测并拒绝这些变异体,这个过程称为 杀死变异体(killing the mutant。测试套件的编写质量可通过其被杀变异体的占比来衡量,也可以设计新的测试用例来杀死更多变异体。

注意

变异测试的内容已超纲,书中并未详细展开。具体情况可参考普渡大学计算机科学教授 Aditya P. Mathur 教授编著的 Foundations of Software Testing / 2e(2013 年 5 月出版)。

根据该书定义,将一个 活跃变体(live mutant 同其父体程序区分开的过程,又称作 杀死(killing 一个变体。

原文:Note that distinguishing a mutant from its parent is sometimes referred to as killing a mutant.

考虑下列简化程序逻辑:

if(!a) {
b = 1;
} else {
b = 2;
}

一个强大的变异测试满足以下条件:

  • 测试到达了变异后的 if 条件;
  • 测试会沿着与初始正确分支不同的分支继续执行;
  • 变更后的 b 值会传播到程序输出结果中,并被测试所验证;
  • 由于该方法返回了错误的 b 值,测试终将失败。

编写良好的测试必须能判定变异测试的失败,从而证明它们最初覆盖了必要的逻辑条件。

最有名的 Java 变异测试框架是 Pitest(https://pitest.org/)。

6.9 开发周期中的测试

为了考察不同类型的测试在整个开发周期中的分布情况,作者将整个开发周期(带 CI/CD 工作流)划分为四个核心阶段(开发阶段、集成阶段、验收压力测试阶段、预生产阶段),并给出了各阶段的特点和对应测试类型的主要任务。

以下是开发周期的四个核心阶段:

接着是不同测试类型基于上述分类的分布情况:

其中左下角的准生产环境虽然过于理想,但对于开发者建立完备的知识结构还是有益处的。作者也承认很多公司可能没有如此理想的阶段划分,甚至出于各种现实因素考虑不得不简化甚至取消整个测试环节(躺枪)。但从开发者个人发展的长远考虑看,还是应该从自身做起,重视测试环节。

JUnit 最佳实践:持续的回归测试

这里揭示了软件功能持续迭代的真实过程:利用代码的可复用性,新功能的开发总是建立在微调现有功能模块的基础上的。有了 JUnit 单元测试,微调对原来的功能特性造成的影响可以很快得到响应,因为这些测试用例是可以自动运行的。用变更前的测试用例来防范新变更产生的问题,其实也是回归测试的一种。任何类型的测试都可以用作回归测试,但最基础且最有效的防御手段,还是 在每次变更后运行单元测试

至于单元测试本身的可靠性如何,可以通过上节的变异测试进行定量评估。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/969851.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年热门的三维调节缓冲托底轨厂家推荐及选购参考榜

2025年热门的三维调节缓冲托底轨厂家推荐及选购参考榜行业背景与市场趋势随着家居五金行业的快速发展,三维调节缓冲托底轨作为高端家具的核心配件,其市场需求呈现持续增长态势。据《2024-2025中国家居五金行业白皮书…

2025年组织研磨器直销厂家权威推荐榜单:三维电磁振动筛分仪/电路板研磨机/冷冻研磨仪源头厂家精选

在实验室技术与材料科学快速发展的背景下,组织研磨器作为样品前处理的核心设备,其性能直接关系到分析结果的准确性与效率。行业数据显示,2025年全球实验室样品前处理设备市场规模预计达86亿美元,中国市场年均增长率…

linux date 日期

date 是 Linux 系统中用于显示或修改系统日期和时间的命令。它是一个非常常用的命令,适用于大多数 Linux 发行版。? 常用 date 命令 1. 显示当前日期和时间 date输出示例:2025-03-15 14:30:452. 显示当前日期(不显…

2025年口碑好的成都全品类五金厂家实力及用户口碑排行榜

2025年口碑好的成都全品类五金厂家实力及用户口碑排行榜行业背景与市场趋势五金行业作为制造业和建筑业的重要配套产业,近年来在成都地区发展迅猛。根据中国五金制品协会最新发布的《2024年中国五金行业白皮书》显示,…

2025年口碑好的蛇形帘系统配件厂家最新TOP排行榜

2025年口碑好的蛇形帘系统配件厂家最新TOP排行榜行业背景与市场趋势随着智能家居概念的普及和消费者对生活品质要求的提升,窗帘系统作为家居装饰的重要组成部分,正经历着从传统向智能化、功能化方向的转型升级。据《…

2025年比较好的小型平板硫化机行业内口碑厂家排行榜

2025年小型平板硫化机行业内口碑厂家排行榜行业背景与市场趋势小型平板硫化机作为橡胶、塑料等高分子材料加工领域的关键设备,近年来随着新材料产业的蓬勃发展,市场需求持续增长。据中国橡胶工业协会统计数据显示,2…

JSAPIThree 地图视野控制学习笔记:让地图动起来

这是一篇关于 JSAPIThree(mapvthree)地图视野控制的学习笔记,以初学者的视角记录如何控制地图视野、切换视角、转换坐标等功能的完整学习过程。作为一个刚开始学习 mapvthree 的小白,今天要学习地图视野控制了!听…

2025 最新推荐!香港保健品源头厂家权威榜单:原料仓储常备 + 产能稳定,国际认证达标企业实力解析优质香港保健品/天然香港保健品/可靠香港保健品/易吸收香港保健品公司推荐

引言 健康消费全球化趋势下,高品质保健品成为市场刚需,而源头厂家的合规性、产能稳定性与技术实力直接决定合作价值。本次榜单依托国际注册执业营养师公会、国际质量与标准学会等四大权威机构联合推出的 “循证功效认…

2025年口碑好的冰雕雪雕厂家推荐及选择参考

2025年口碑好的冰雕雪雕厂家推荐及选择参考行业背景与市场趋势冰雪艺术产业近年来在中国北方地区蓬勃发展,据《2024年中国冰雪文化产业白皮书》数据显示,2023年全国冰雪景观市场规模已达到87.5亿元,同比增长18.3%。…

Solon AI 开发学习 - 2chat - Hello World

本文介绍了如何使用Solon-AI框架结合本地部署的Ollama服务调用Llama3.2等大语言模型的完整流程。文章提供了从环境搭建到实际调用的详细步骤,并附有配置示例和效果截图,帮助开发者快速实现本地大语言模型的集成应用。…

2025年靠谱的电压互感器品牌厂家排行榜

2025年靠谱的电压互感器品牌厂家排行榜行业背景与市场趋势随着全球能源转型和智能电网建设的加速推进,电压互感器作为电力系统中不可或缺的关键设备,其市场需求持续增长。根据中国电力企业联合会最新发布的《2024-20…

libcurl FTP路径规范化漏洞解析:编码%2e%2e导致目录穿越

本文详细分析了libcurl在处理FTP路径时存在的安全漏洞,攻击者可通过编码的%2e%2e序列实现目录穿越。文章包含漏洞原理、复现步骤、影响分析和修复建议,涉及CWE-22路径遍历和CWE-20输入验证不当等安全问题。libcurl F…

2025 最新推荐修脚加盟品牌榜单:国际协会测评认证,非遗技艺 + 成熟运营体系优选指南修脚加盟培训 / 足疗修脚加盟 / 采耳修脚加盟 / 修脚培训加盟公司推荐

引言 随着健康消费升级,足部护理赛道持续扩容,加盟创业需求激增,但市场品牌良莠不齐导致决策难度加大。本次榜单依托国际足部护理协会(IFCA)近三年测评数据,结合第三方调研机构对全球超 2000 家加盟门店的运营监…

2025年BIP系统口碑排行揭晓,黑马系统强势登顶!好生意/用友 T3/易代账/协同云/税务云/好业财/制造云BIP服务商推荐排行榜单

行业权威榜单发布 随着企业数智化转型进程加速,商业创新平台(BIP)作为企业数字化转型的核心载体,其市场表现备受关注。基于公开数据和市场调研,我们综合产品能力、技术架构、客户满意度等维度,对当前市场上表现突…

2025年杭州汽车美容服务权威推荐榜单:汽车保护膜/汽车改色/高端汽车贴膜服务精选

在汽车消费升级与个性化需求增长的驱动下,杭州汽车美容服务市场呈现专业化、高端化、精细化发展趋势。据行业统计,2025年中国汽车后市场规模预计突破2万亿元,其中美容贴膜类服务年增长率达15%。为帮助车主精准筛选优…

2025年体育科技与运动表现分析国际学术会议(ICSTPA 2025)

2025年体育科技与运动表现分析国际学术会议 2025 International Conference on Sports Technology and Performance Analysis (ICSTPA 2025) 【ACM 出版 - EI检索快速稳定|往届已检索】 ICSTPA 2024已成功被 EI 数据库…

2025年热门的烟台包装用户口碑最好的厂家榜

2025年热门的烟台包装用户口碑最好的厂家榜行业背景与市场趋势随着中国制造业的持续升级和消费市场的不断扩大,包装行业作为配套产业迎来了快速发展期。根据中国包装联合会最新数据显示,2024年中国包装行业市场规模已…

算一算你的一餐,为地球“减负”多少?

你有没有想过,我们每天的一日三餐,除了关乎健康和美味,也与远方的冰川、森林和气候有着微妙的联系? 最近,我接触到一个很有意思的在线小工具——“膳食碳足迹计算器”。它用最直观的方式告诉我们,每一餐饭的背后…

基于Simulink实现卡尔曼滤波

一、系统建模基础 1. 状态空间模型定义 卡尔曼滤波的核心是建立系统的状态方程和观测方程:状态方程:\(A\):状态转移矩阵 \(B\):控制输入矩阵 \(w_k\):过程噪声(\(N(0,Q)\))观测方程:\(H\):观测矩阵 \(v_k\):…