1)相互独立的测试:高内聚和松耦合
2)测试清单:从使用者角度得出系统需要实现的需求;划分出大概结构;对每一部分列出需要测试的每种可能性;对于目前还未实现的操作将其空版本写在清单上;这一轮编程后需要的重构。在写测试可能会引入新的测试,写在清单上。
3)测试优先:一种设计和控制规模的方法,至少在中等压力下可以使用
4)断言优先:编写测试时,从断言开始,逆向得到需要的测试类
5)测试数据:容易理解的数据。永远不要用同一常量表达多种意思。使用真实数据。
1)第一步测试:从测试清单中何处入手?能够打开思路且知道如何实现的测试。
2)开始编写测试:先使用典型的输入和输出构造测试,再将输入拓展完成测试。
3)说明测试:使用测试代替序列图说明设计
4)什么时候为外部软件编写测试:第一次准备使用该包内的新功能时
5)bug修改时,列出清单,先写测试,修改源代码,通过后再继续。
6)休息:当不知道怎么实现时,先使用伪实现。
1)测试太大周期会太长,应对大测试分解为小测试,最后再处理大测试
2)对象间交互:最好是基于接口测试,使用mock对象模拟接口完成测试
3)测试消息调用顺序:当调用消息时向日志字符串追加数据。
4)离开编程一段时间:让编写的测试有编译错误或不能正确运行
5)提交前确保所有的测试都通过
使测试尽快运行
1)伪实现:返回一个常量并逐渐用变量代替常量,直至伪实现成为真正的实现。能判断测试是否正确
2)真正的实现
3)三角法:同一功能写两个测试,从而明确应该如何设计和重构,只有不知道怎么实现时。
当在实际开发中,如果知道该写什么将使用真正的实现,一旦测试没有通过,则退回去采用伪实现,重构直到得到正确的代码,当我恢复自信时,又开始使用真正的实现。
4)从一到多:实现作用于一个集合集的操作,先从单体开始,最后到集合集。
5)隔离变化:重构或修改时尽量减少同时变化的数量。
丰富测试用例
先不改代码,增加参数;
修改函数功能;
删除无用参数;
1) tearDown:可以将释放资源放在该函数中,对于具体的test失败,该方法依然会调用。
2) testMehtod:名称应包含编写测试的缘由
3) 确保测试与时间无关,不要依赖使用过期的数据进行测试。导致在随后的维护过程中很难重现测试。
4) 当你试图打印输出一些信息或调试一个表达式时,写一些测试代码来替代那些传统的方法。
5) 不要认为压力大,就不写测试代码。相反编写测试代码会使你的压力逐渐减轻,应为通过编写测试代码,你对类的行为有了确切的认识。你会更快地编写出有效率地工作代码
1) Reconcile Differences:统一两端相似代码?
先使用extract method减少函数规模
使用eclipse文件比较,分开不同和相同的代码
2) isolate change:对要修改的部分进行隔离,方法有:
提取函数,提取对象,方法对象
3)Migrate data:从一种数据类型变为另一种数据类型,如One to Many。
创建新数据,将旧数据转换为新数据;将新数据作为增加的参数;在函数内部使用新格式替换就格式数据;删除旧格式参数;将调用端旧格式换为新格式数据
4)Add parameter
先在接口中添加,使用编译器帮助你添加。用于函数功能的扩展。
5)把方法中的参数变为构造函数中的参数。
实现:将参数移入函数中作为局部变量,并随便赋值;使用 refractor菜单中的Convert local value to Field;修改构造函数。
6)表达式的处理:
extract local variable:提取表达式为一个局部变量。
Introduce Parameter提取表达式为函数参数。
extract constant:提取表达式如字符串为一个常量。必须选中引号(不用手写了,哈哈)
7)convert annoymous class to nest:将匿名类转换为成员类
8)variable的处理
Encapsulate Field:将filed用getter和setter包装,调用处也会改变
Convert local value to Field:将局部变量转换为field,并使用构造函数等初始化
9)Use SuperType Where Posssible:选中类型,尝试使用其基类替换
10)Introduce Factory:选择构造函数,使用factory函数代表该构造函数的使用地方。
11)Introduce Indirection:解决静态函数调用非静态函数。
12) 测试代码重构
使用合适的断言,并提供message
将信息整合到 setup 和 teardown中
保持测试的独立:mock类等