SQ3R阅读法:
Survey:阅读之前的浏览,查阅
1、书名:《Pragmatic unit testing:in java with Junit》,中文译名《单元测试之道Java版:使用JUnit》,是作者编著的程序员修炼三部曲中的一部,分别是《Pragmatic Version Control》、《Pragmatic Unit Testing》和《Pragmatic Automation》。
2、作者:
关于作者:
Andy Hunt(Andrew Hunt),著名软件开发书籍方面作者,是敏捷软件开发联盟的17位奠基人之一,和搭档David Thomas合著一系列经典书籍:
《The Pragmatic Programmer》
《Pragmatic Version Control Using CVS》
《Pragmatic Unit Testing in Java with JUnit》
《Pragmatic Unit Testing in C# with Nunit》
《Pragmatic Thinking and Learning: Refactor Your Wetware》
3、大体内容:
(1)没有介绍junit如何实现, 也没有大篇幅的介绍如何使用junit, 或者介绍junit的一些高级用法; 它
讲了做单元测试的一些原则, 单元测试测什么, 什么样的单元测试才是一个好测试。
Question:提出问题
Read:阅读全书
第一章 序言(introduction)
1、单元测试的设计目的?
单元测试设计目的
并不是为了获得一些更好的整体质量。它并不是一个针对最终用户、项目经理和开发组长的工具;而是有程序员自己来完成,并且
最终受益人也是程序员自己。我们为了自身的利益去使用单元测试,从让我们的工作变得更加轻松。
2、什么是单元测试?
单元测试是开发者编写的一小段代码,用于检验被检测代码的一个很小、很精确功能是否正确。
3、执行单元测试的目的?
执行单元测试是为了证明某段代码的行为确实和开发者所期望的一致。
第二章 首个单元测试(your first unit tests)
第三章 使用JUnit编写测试(writing tests in junit)
1、
JUnit中的各种断言
(1)assertEuqals([String message],expected,actual)——“[]”中为可选参数;
(2)assertEuqals([String message],expected,actual,tolerance)——tolerance代表容忍度,用于测试精度;
(3)assertNull([String message],Object object)——测试是否为空;
(4)assertNotNull([String message],Object object)——测试是否为空;
(5)assertSame([String message],expected,actual)——测试两个参数是否引用同一对象,不是的话失败;
(6)assertNotSame([String message],expected,actual)——测试两个参数是否引用不同对象;
(7)assertTrue([String message],boolean condition)——验证给定的条件是否为真;
(8)assertFalse([String message],boolean condition)——验证给定的条件是否为假;
(9)fail([String message])——注定会失败,用于标记不应到达的分支;
2、
JUnit测试骨架
(1)一个import语句引入所有junit.framework.*下的类;
(2)一个extends语句让你的类从TestCase继承;
(3)一个调用super(String)的构造函数。
第四章 测试哪些内容:Right-BICEP(what to test:Right-BICEP)
1、
6个值得首先进行测试的方面?
(1)Right——结果正确与否;
a、如果测试代码运行正确,怎样确实它确实是正确的,而不是看起来是正确的?
- 使用数据文件——数据尤其可能出错,尤其是手工计算的数据;
(2)B(Boundary)——是否所有的边界条件是正确的;
- 找出边界条件是做单元测试中最有价值的工作之一,因为bug一般都出现在边界上;
- 简单的记忆方法:单词CORRECT;
- Conformance(一致性)——结果是否和预期一致;
- Ordering(顺序性)——结果是否应该是这样的;
- Range(区间性)——结果是否位于合理的最小值和最大值之间;
- Reference(依赖性)——代码是否引用了一些不在代码本身控制范围之内的外部资源;
- Existence(存在性)——结果是否应该存在;
- Cardinality(基数性)——是否恰好有足够的值;
- Time(相对或绝对的时间性)——所有事情的发生是否是有序的,是否是在正确的时刻?是否恰好及时?
(3)I(Inverse)——能查一下反向关联吗?
a、对于一些结果正确与否,我们可以
使用反向的逻辑关系来验证。(如检查是否插入了某条数据,可以使用反向逻辑,通过查询该条记录来验证)
(4)C(Cross-Check)——能用其他手段交叉检查一下结果吗;
a、通常来讲,任何一个计算都会有一个以上的算法;可以使用不同的算法来实现交叉检查结果;
(5)E(error Conditions)——是否可以强制错误条件发生;
a、现实世界中各种错误频繁发生,要强制使代码产生错误,已验证对错误事件的处理;
b、一般常见的错误有如下几种:
- 内存耗光
- 磁盘用满
- 时钟出现问题
- 网络不可用或者出现问题
- 系统过载
- 调色板颜色数目有限
- 显示分辨率过高或过低
(6)P(performance)——是否满足性能要求。
a、确保系统性能问题。
第五章 CORRECT边界条件(CORRECR boundary conditions)
第六章 使用mock对象(Use Mock Objects)
1、单元测试的目标是一次只验证一个方法,但是如果一个方法依赖于其他难以操控的东西,如网络、数据库等,怎么办?——使用mock对象
2、
mock对象——真实对象在测试期间的替身!
伪装出真实世界的部分,然后集中精力写好测试部分的代码!
3、使用mock对象时的三个步骤
a、使用一个接口来描述这个对象
b、为产品代码实现这个对象
c、以测试为目的,在mock对象中实现接口
第七章 好的测试具有的特性(properties of good tests)
1、
好的测试应该具备的特性——A-TRIP
(1)自动化(
Automatic)
- 自动化包括两个方面:调用测试自动化、检查结果自动化
(2)彻底的(
Thorough)
- 彻底是指测试了所有的可能情况。
(3)可重复(
Repeatable)
- 独立于周围的环境,能够以任意的顺序一次又一次地执行,并且得到相同的结果。
(4)独立的(
Independent)
- 对立于其他环境,独立于其他测试。
(5)专业的(
Professional)
- 测试代码必须和产品代码一样
第八章 在项目中进行测试(testing on a project)
1、测试代码的存放位置
(1)同一目录
- 好处:测试代码能够访问产品代码中protected成员变量和函数;
- 坏处:测试代码混淆在产品代码中。
- 决策:小项目使用,大项目不能使用;
(2)子目录
- 好处:测试代码远离产品代码,但不至于很远;
- 坏处:测试代码和产品代码在不同的包中,不能直接访问protected成员变量和函数;除非测试代码中使用了产品代码的子类,且子类暴露了那些成员;
- 决策:不建议使用。
(3)并行树
- 好处:测试代码和产品代码不在混淆在一起;
- 坏处:测试代码大大远离产品代码;
- 决策:测试代码都在一个包中,享受了先前的访问权利。建议采用!
2、测试的礼貌
(1)时刻保证测试代码能够正确运行!——无论是独自测试还是与别人一起测试!
3、测试的时机
(1)编写很函数时;
(2)修正bug后;
(3)每次成功编译后;
(4)每次更新代码后;
(5)持续不断地运行测试;
4、对于遗留代码的测试
(1)对于新编写的代码,同时编写测试代码;
(2)对于已经存在的代码,只对最容易出问题的代码进行测试;
(3)对于此种情况,单元测试的最重要的作用是防止倒退:避免维护性的更正和修缮导致现存功能产生bug。
(4)回归测试至关重要!!
第九章 设计问题(Design Issues)
Recite:复述全文
Review:回顾全书