Java理论与实践:平衡测试,第1部分:不要仅编写测试,还要编写bug检测器

对于许多团队来说,单元测试现在是开发过程的一个主要部分;JUnit 之类 的框架可以进行无损测试,尽管我们并不喜欢它,宁愿为某些 代码编写某些 测 试。单元测试运行效率很低,只能测试单个代码片段,并且,一般情况下,测试 代码的重用性通常很也低 —— 昨天为组件 A 编写的测试不能很好地用于测试 组件 B(示例代码除外)。

典型的单元测试场景

在发现 bug 时,要做的第一件事是什么?您可能只是想去修复它,但是,在 长时间的运行中,这不是一个最有效的方法。在许多开发部门中,处理 bug 的 过程如下:

针对 bug 编写测试用例

确保测试用例在遇到 bug 时运行失败

修复 bug

确保测试用例通过

确保其他测试套件仍能通过

检查修正和测试用例,形成版本控制

将修正记录在 bug 跟踪系统中

尽管此方法在短期内比仅修复 bug 要多做许多工作,但它提供了许多更有价 值的东西:获得修复 bug 的更多信心,因为您已经对它进行了测试;获得 bug 将不会再出现的更多信心,因为测试用例是回归测试套件的一部分。在版本控制 系统和 bug 跟踪系统之间,还可以获得一个记录,该记录描述了 bug 是什么以 及如何修复它 —— 这是非常有用的信息,其他人会从中受益。

如果进取心较强,那么可以思考一下 bug 是怎样出现的,并在其他位置查找 同一错误。如果在别处发现同一错误,那么可以对这些 bug 进行测试和修复。 单元测试作为质量管理工具的主要弱点是每个测试用例只能测试一个代码片段。 因为测试用例是专为每个组件和每个潜在错误模式设计的,所以只有编写足够多 的单元测试才能测试大量的产品,这非常耗时并且代价高昂。

QA 经济

测试是一种基本的质量管理工具,我们知道仅有多组测试用例还不足以找出 复杂软件片段中的所有 bug。事实上,对于任何优秀程序而言,“查找所有 bug ” 是不可能实现的目标。据估计,NASA 向每个开发人员提供了 20 个测试程序 (大大超过任何商业实体)来负责质量评价 (QA) —— 但软件仍有缺陷。因此 ,质量评价的目标不应是查找所有的 bug,因为这是不可能的。相反,质量评价 的目标应该是提高代码运行良好的信心,从而最大程度地提供可用资源。

要高效运行质量评估量 (QA),则需要对可用 QA 方法中的可用资源做预算, 这样才能最大限度地提高信心。覆盖范围大的测试套件可以提高我们对代码使用 的信心,因为它进行了一次彻底的代码审查。执行两次比执行一次较果好,因为 每次都会发现另一次可能错过的错误。两次同样遵循收益递减规则,所以测试价 值为 X 美元和代码审查价值为 Y 的 QA 计划要比价值为 X+Y 的任何一次测试 或代码审查的效果好。

添加静态分析

静态分析是在不运行代码的情况下对其进行分析的过程,它与进行前面的代 码审查时我们执行的操作非常相似,或者与标记可疑结构时 IDE 执行的操作非 常相似。静态分析是添加到 QA 混合(QA mix)中的一项优良技术,因为它擅长 查找其他方法(如测试和代码审查)可能错过的错误。静态分析相对比较容易一 些,不像单元测试那样必须为要测试的每个类重新编写测试,您可以在任何代码 上运行静态分析工具。

FindBugs 是一种开放源码的静态分析工具,它包含用于许多常见 bug 模式 的 bug 模式检测器,令人惊讶的是,即使在测试良好的软件中,FindBugs 也常 常会发现一些 “沉默” 的 bug,但是单元测试和专业代码审查都可能错过这些 bug。FindBugs 还允许编写新的 bug 模式检测器,并将它们包装为插件,所以 如果一组标准的检测器不能按您的需要执行,那么您可以很容易地编写自已的检 测器。此扩展性使 FindBugs 成为非常强大的质量管理工具,因为当发现新类型 的错误时,可以针对该错误编写检测器,并在整个代码基址中搜索该错误。

静态分析的主要作用是分析输出,并确定报告的条目是真的 bug 还是假警报 。编写的部分优秀分析工具或 bug 模式检测器会管理误报率;核心 FindBugs 包中的检测器已经进行了调优,目的是使误报率不超过 50 %,这样分析输出时 不会有太多的烦麻。(将此阈值与针对 C 的 lint-like 工具进行比较,后者常 常发出许多假警报,使用时相当耗时。)

时间: 2024-10-26 06:13:29

Java理论与实践:平衡测试,第1部分:不要仅编写测试,还要编写bug检测器的相关文章

Java理论与实践:平衡测试,第2部分:编写和优化bug检测器

这一简短系列的 第 1 部分 介绍了如何进行有效测试,它构建了 FindBugs 插件来查找一个简单的 bug 模式(只需调用 System.gc() 即可).Bug 模式会 标识有问题的编码实践,它们常常位于 bug 所在的区域.当然,并不是所有出 现 bug 模式的地方都一定出现 bug,但这并不能抹杀 bug 模式检测器的巨大作 用.一个有效 bug 模式检测器的主要功能是发现更高百分比的可疑代码,使该 模式具有更大的使用价值.创建 bug 模式检测器可以提高使用价值:创建检测 器之后,无

Java理论与实践: 平衡测试,第3部分:用方面检验设计约束

面向方面编程(AOP)是项大有前途的新技术,但是采用新技术可能有风险( 当然,不 采用新技术也会有风险).与所有的新技术一样,通常来说,最好是 沿着一条可以管理风险的路径来采用它们.如果用 AOP 来执行策略和测试,就 可以从 AOP 得到降低风险的好处.因为方面不会进入生产,所以不会出现技术 破坏代码稳定性或开发过程的风险,但却会有助于开发质量更好的软件.用方面 进行测试也是学习方面的工作方式,并体验这项激动人心的新技术的好方法. 组合测试方法 正如我在 第 1 部分 中讨论过的,QA 的目的

Java理论与实践专题

Java理论与实践: JDK 5.0中更灵活.更具可伸缩性的锁定机制 Java理论和实践: 一个有缺陷的微基准的剖析 Java理论和实践: 理解JTS ― 平衡安全性和性能 Java理论和实践: 理解JTS ― 幕后魔术 Java理论和实践: 安全构造技术 Java理论与实践: 平衡测试,第3部分:用方面检验设计约束 Java理论与实践:平衡测试,第2部分:编写和优化bug检测器 Java理论与实践:平衡测试,第1部分:不要仅编写测试,还要编写bu Java理论与实践: 您的小数点到哪里去了?

Java 理论与实践: JDK 5.0 中更灵活、更具可伸缩性的锁定机制

伸缩 内容: synchronized 快速回顾 对 synchronized 的改进 比较 ReentrantLock 和 synchronized 的可伸缩性 条件变量 这不公平 结束语 参考资料 关于作者 对本文的评价 相关内容: Java 理论与实践 系列 Synchronization is not the enemy Reducing contention IBM developer kits for the Java platform (downloads) 订阅: develop

Java理论与实践: 您的小数点到哪里去了?

许多程序员在其整个开发生涯中都不曾使用定点或浮点数,可能的例外是, 偶尔在计时测试或基准测试程序中会用到.Java语言和类库支持两类非整数类型 ― IEEE 754 浮点( float 和 double ,包装类(wrapper class)为 Float 和 Double ),以及任意精度的小数( java.math.BigDecimal ).在本月的 Java 理论和实践中,Brian Goetz 探讨了在 Java 程序中使用非整数类型时一 些常碰到的陷阱和"gotcha". 虽

Java理论和实践: 安全构造技术

Java 语言提供了灵活的.看上去很简单的线程功能,使得您很容易在您的应用程序中使用多线程.然而,Java应用程序中的并发编程比看上去要复杂:在 Java 程序中,有一些微妙(也许并不是那么微妙)方式会造成数据争用(data race)以及并发问题.在这篇 Java 理论和实践中,Brian探讨了一个常见的线程方面的危险:在构造过程中,允许 this 引用逃脱(escape).这个看上去没有什么危害的做法可以在 Java 程序中造成无法可预料和不期望的结果. 测试和调试多线程程序是极其困难的,因

Java 理论与实践: 非阻塞算法简介

[本文转载自Java 理论与实践: 非阻塞算法简介]Java 5.0 第一次让使用 Java 语言开发非阻塞算法成为可能,java.util.concurrent 包充分地利用了这个功能.非阻塞算法属于并发算法,它们可以安全地派生它们的线程,不通过锁定派生,而是通过低级的原子性的硬件原生形式 -- 例如比较和交换.非阻塞算法的设计与实现极为困难,但是它们能够提供更好的吞吐率,对生存问题(例如死锁和优先级反转)也能提供更好的防御.在这期的 Java 理论与实践 中,并发性大师 Brian Goet

Java 理论与实践:变还是不变?

不变对象具有许多能更方便地使用它们的特性,包括不严格的同步需求和不必考虑数据讹误就能自由地共享和高速缓存对象引用.尽管不变性可能未必对于所有类都有意义,但大多数程序中至少有一些类将受益于不可变.在本月的 Java 理论与实践中,Brian Goetz 说明了不变性的一些长处和构造不变类的一些准则.请在附带的论坛中与作者和其他读者分享您关于本文的心得.(也可以单击文章顶部或底部的"讨论"来访问论坛.) 不变对象是指在实例化后其外部可见状态无法更改的对象.Java 类库中的 String.

Java理论与实践: 垃圾收集简史

Java 语言可能是使用最广泛的依赖于垃圾收集的编程语言,但是它并不是第 一个.垃圾收集已经成为了包括 Lisp.Smalltalk.Eiffel.Haskell.ML. Scheme和 Modula-3 在内的许多编程语言的一个集成部分,并且从 20 世纪 60 年代早期就开始使用了.在 Java 理论与实践的本篇文章中,Brian Goetz 描述 了垃圾收集最常用的技术. 垃圾收集的好处是无可争辩的 ―― 可靠性提高.使内存管理与类接口设计 分离,并使开发者减少了跟踪内存管理错误的时间.著