第一章 为什么使用单元测试

简介:
第一章 为什么使用单元测试

  1.1 程序员的工作——修改软件

  修改既有代码是程序员谋生的手段。但是为什么我们需要去修改软件呢?修改软件有以下4个主要起因:

  ● 修正bug

  ● 添加新特性(feature)

  ● 改善设计

  ● 优化资源使用

  这4项都与软件的“行为”密切相关,见下表。


软件的既有行为
软件的新行为
修正bug
改变软件的既有行为
增加新行为
添加新特性
保持软件的既有行为,完全不修改既有代码
改善设计
保持软件的既有行为,但软件的可维护性得到提升
优化资源使用
保持软件的既有行为,但软件的性能得到提升

  通过这张表格我们看出:只有在修正bug时,我们才需要改变软件的既有行为,而在其他情况下,我们都需要保持住软件的既有行为。如果我们在改善设计,优化,或添加新特性时改变了软件的既有行为,那我们实际上是给软件引入了bug。

  可是程序员的工作就是修改软件,所以我们有很多的“机会”给软件引入bug。有什么办法能让我们的生活轻松一点,而不用因为修改代码引入bug而担惊受怕吗?

  1.2 软件夹钳——测试

  我们已经看到:在大多数情况下,我们希望对软件所做的改动不会改变系统的既有行为。即使是对于修正bug这种情况,我们也希望一旦bug被修正,那么修正后的正确行为能够得到保持,而不会被再之后的代码修改所改变。怎样做到这一点呢?

   让我们这样想想:如果我们能在对代码进行改动之前,用一种“软件夹钳”(software vise)来固定住软件的既有行为,那么我们就可以放心大胆地去修改代码了。那么,又是什么可以来充当“软件夹钳”呢?答案是:测试。我们可以这样想一 下:当一段代码被一组良好的测试所覆盖时,我们就可以放手去修改这段代码,并在修改完成之后立即运行这组测试,来验证我们的修改并没有改变既有行为而引入 bug。如果确实改变了既有行为,那么测试就会明确无误地发出警报。由此可见,测试就是程序员所需要的“软件夹钳”。

  1.3 单元测试与集成测试之争

  我们已经知道了“测试”就是程序员所需要的“软件夹钳”。但是测试分为单元测试和集成测试,程序员需要哪种测试呢?让我们来分析一下程序员需要什么样的测试,这样或许我们就能知道程序员应该更偏向于哪种测试了。

  ● 程序员需要的测试应该是能帮助程序员定位错误的,这样程序员才会真正地从测试中得到“实惠”。

  ● 程序员需要的测试应该是很容易执行的,最好是只需点击一个按钮或键入一条命令,这些测试就能运行,而无需费时费力地去搭建测试环境及准备测试数据或仪器。

  ● 程序员需要的测试应该是运行速度很快的,最好能在几分钟内完成,这样程序员才能快速地得到反馈,采取下一步动作。

  ● 程序员需要的测试应该是易于写就的,而不愿意对代码基大动干戈,这样程序员才会愿意去写这些测试。

  ● 程序员需要的测试应该是自动化的,可重复的。这样程序员才会愿意重复多次地去运行这种测试。

  比对程序员的需求,我们可以发现集成测试往往不能满足程序员的这些需求:

  ● 集成测试由于涉及多个模块,因此往往不能提供准确的错误定位信息。

  ● 集成测试的执行时间一般较长(小时级),这不能给程序员带来快速反馈。

  ● 集成测试可以自动化执行,但前提是把测试环境和测试数据等事先准备好。

  ● 集成测试由于不太容易写就,通常不是由程序员写就,而由专门的测试人员写就。

  相反,单元测试,尤其是良好的单元测试,恰恰正是程序员所需要的那种测试:

  单元测试针对单个类或单个方法,能很有成效地帮助程序员准确定位问题所在。

  单元测试应该是执行时间很短的,全部执行也只需5到10分钟,程序员正好可以去喝喝咖啡。

  单元测试是一种“虚拟”测试,重在测试代码逻辑,因此一般不需要真实测试环境和测试数据的支持。

  单元测试是很容易写就的,尤其是有单元测试框架的帮助时。

  由此可见,对于程序员而言,需要的是单元测试。程序员使用单元测试来充当软件夹钳,并在修改代码时获得快速反馈,从而更有信心地投入到修改软件的工作中。

  1.4 进行单元测试的其他好处

  我们已经知道了单元测试带来的一个好处:它可以充当程序员的“软件夹钳”,在程序员修改软件的过程中给予程序员快速的反馈,帮助程序员定位问题,避免引入bug。单元测试就只有这一个好处吗?不是的。下面我们就来看看引入单元测试带来的其他好处。

  1.4.1 单元测试是代码的“活文档”

  让文档及时反映软件设计和代码的最新情况,这是一个颇有挑战性的问题。一种较好的思路是:使用“内部”文档,即把文档同代码“拴”在一起。这样当代码发生改变的时候,文档也能相应更新。注释就是一种内部文档,良好的注释应该反映代码的最新状况。

  类比来看,单元测试同样也是内部文档,因为单元测试本质上也是描述了被测类或被测方法的行为。对软件行为不了解的程序员,可以通过阅读单元测试 代码来理解软件的行为。同注释相比,单元测试还具有一个更好的特性:它是一种“可执行”文档。如果单元测试在被执行时无法通过,那么说明要么单元测试没有 反映当前代码的真实状况,要么说明代码中有bug。无论哪种情况,程序员都需要修改某一方,以保持两者的一致。

  1.4.2 具有可测试性的软件具有更高的质量

  近年来流行的极限编程方法论推崇“测试驱动开发”。我们认为,“测试驱动开发”并不一定要求必须先有测试后有代码,而关键在于要求在设计软件和 实现编码时,一定要预先把软件的可测试性考虑周全。这种可测试性的重要体现就是能够方便地将单个类或方法纳入单元测试之中。具有可测试性的软件的质量往往 高于不具有可测试性的软件,为什么这样说呢?

  ● 一个类能够被方便地纳入单元测试,往往说明这个类职责单一,也就是说它满足“单一职责原则”。

  ● 一个类能够被方便地纳入单元测试,往往说明它与其他类之间的耦合程度较低,相互依赖性较小,而且很可能满足“依赖抽象原则”和“开放-封闭原则”。

  因此, 具有可测试性的软件,也更有可能是满足良好设计原则的软件,所以往往质量更高。


本文出自seven的测试人生公众号最新内容请见作者的GitHub页:http://qaseven.github.io/

目录
相关文章
|
存储 数据采集 XML
再谈主数据管理|一文读懂主数据项目实施
主数据管理是企业改善其关键数据资产(如产品数据,资产数据,客户数据,位置数据等)的一致性和质量的必要数据管理活动。
|
6月前
|
人工智能 运维 API
评测|零门槛,即刻拥有DeepSeek-R1满血版
在大模型浪潮席卷而来的当下,人工智能正以前所未有的速度渗透进各行各业。对于开发者群体而言,这无疑是一场意义深远的变革。当下,缺乏AI相关应用开发经验或许尚可立足,但展望未来,一年之后,若仍在这一领域毫无建树,在职场上恐将举步维艰,面临求职困境。 对于AI领域的新手小白来说,急切需要解决两大关键问题:一是如何以最快捷的方式上手使用AI相关应用,快速踏入AI大门;二是怎样寻觅合适的业务场景,切实开展AI实践操作,积累宝贵经验。 值得庆幸的是,阿里云为广大开发者提供了丰富且优质的机会。在接下来的内容中,将深入剖析阿里云在AI领域的全方位布局,并详细介绍如何借助阿里云平台,实现云上调用满血版DeepS
209 6
评测|零门槛,即刻拥有DeepSeek-R1满血版
|
9月前
|
Linux iOS开发 MacOS
Matplotlib 中文显示
Matplotlib 中文显示
366 5
|
11月前
|
存储 定位技术 数据库
介绍一下数据库的备份和恢复策略
【10月更文挑战第21】介绍一下数据库的备份和恢复策略
|
11月前
|
存储 搜索推荐 数据库
运用LangChain赋能企业规章制度制定:深入解析Retrieval-Augmented Generation(RAG)技术如何革新内部管理文件起草流程,实现高效合规与个性化定制的完美结合——实战指南与代码示例全面呈现
【10月更文挑战第3天】构建公司规章制度时,需融合业务实际与管理理论,制定合规且促发展的规则体系。尤其在数字化转型背景下,利用LangChain框架中的RAG技术,可提升规章制定效率与质量。通过Chroma向量数据库存储规章制度文本,并使用OpenAI Embeddings处理文本向量化,将现有文档转换后插入数据库。基于此,构建RAG生成器,根据输入问题检索信息并生成规章制度草案,加快更新速度并确保内容准确,灵活应对法律与业务变化,提高管理效率。此方法结合了先进的人工智能技术,展现了未来规章制度制定的新方向。
397 3
|
存储 算法 Java
【干货】如何写一篇还算凑活的博客文章
本文从程序员的角度出发,分享了作者参加掘金启航计划并获得奖品的经历,通过实际写作流程,详细介绍了构思、撰写、美化文章及发布到各大平台的技巧与心得,旨在激发博友们的写作热情。文中还推荐了一些实用的辅助工具和博客平台。
243 0
【干货】如何写一篇还算凑活的博客文章
|
机器学习/深度学习 数据采集 运维
【博士每天一篇文献-综述】2024机器遗忘最新综述之一:A Survey on Machine Unlearning Techniques and New Emerged Privacy Risks
本文综述了机器遗忘技术及其面临的新兴隐私风险,提出了面向数据和模型的分类法,分析了信息窃取和模型破坏攻击手段,探讨了相应的防御策略,并讨论了机器遗忘技术在大型语言模型、联邦学习和异常检测等领域的应用。
282 5
|
SQL JSON Oracle
阿里分布式中间件Seata从入门到精通
阿里分布式中间件Seata从入门到精通
627 96
阿里分布式中间件Seata从入门到精通
|
安全 Windows 数据安全/隐私保护
PowerShell远程连接到Windows
命令行远程连接到Windows
11027 0
|
算法
BWT算法
BWT算法
405 0
BWT算法