25 测试驱动开发模式
准备两个TODO-List一个用于当前,一个用于最近
当发现有事情要做的时候,对其优先级进行判断,将其放到当前或者以后。
集中注意力于当前要做的事情
断言优先
写Case的时候,一开始就写断言,从测试完成时能通过的断言开始写。
测试数据
测试数据要使用容易让人理解的数据,不要为了编排数据而编排数据
不要用同一个常量来表达多种一丝。另外也可以使用真实数据进行测试。
尽量让测试的行为和数据容易理解,比如不使用常量,而是直接使用数字。在assert中加入断言要测试的目的的文字说明
26 不可运行状态
一步测试(One Step Test)
从计划列表中选择具有指导意义而且有把握实现的测试去完成它。
启动测试(Starter Test)
从测试某个实质上不做任何工作的操作开始,这样的测试一般能很快工作。而一个做实际工作的功能的测试可能需要等你解决很多问题,比如:这个操作隶属于哪里?正确的输入是什么?对应的正确输出是什么?等等。结果是其长期无法通过。
回归测试(Regression Test)
对于一个错误情况,编写一个针对该错误的,会出错的,尽可能小的测试。
27测试模式
子测试(Child Test)如果一个测试太大以至于难以运行起来,那么可以先把该测试给分解成几个小的测试,并注释掉本测试。等这些小测试通过之后再继续这个大的测试
模拟对象(Mock Object)
如何测试一个依赖于昂贵的且复杂的资源的对象?创建一个这些资源的模拟版本。
自分流(self Shunt)
如何测试对象间是否正常交互?让测试对象于测试用例而不是期望的对象进行交互。
需要让测试用例类实现所要交互的类的接口。从而进行测试所实现的方法会被正确的调用。
日志字符串(Log String)
如何才能测试使消息调用顺序是正确的?将日志保存在字符串中,当调用一个消息时,就向字符串尾部追加相应的信息。
清扫测试死角(Crash Test Dummy)
如何测试到不大可能被调用的错误代码呢?使用一种特殊的对象调用它,这个对象抛出一个异常而不做任何实际工作。比如实现一个匿名File子类,只实现其createNewFile方法,方法中抛出一个异常,通过这种方式来测试文件系统满了的情况。
不完整测试(Broken Test)
留下半截句子或者一个没有通过的测试用例可以保证你离开代码一段时间之后依然能较快的回忆起原先的想法。
提交前保证所有测试运行通过
当你在团队中变成时如何结束一段编码工作?让所有测试运行起来。
注释掉一些测试代码使测试套件通过是要严格禁止的。
28可运行模式
伪实现(直到你成功)测试不能通过时首先应该执行什么?可以返回一个常量。一旦你能使测试运行起来,那个常量就会逐渐换成用变量表示的表达式。这个方法可以从心理上让我们感到满足,可以让我们集中注意力于当前要解决的问题。
三角法(Triangulation)
怎样可以更适当地利用测试推动抽象呢?只有当你有两个或两个以上的例子时,你才能进行抽象。使用两个针对同一个测试目标的测试例子(或断言),在此基础上对该测试目标的实现进行抽象并实现。
显明实现(Obvious Implementation)
直接实现简单的操作。
从一到多(One to Many)
怎样实现一个作用于对象集合体的操作呢?首先在非集合体中实现,然后使之作用于集合体。
32 掌握TDD
什么可以不必测试?应该测试:条件部分、循环部分、操作部分、多态性。除了不信任,否则不要测试其他来源的代码。
怎样知道自己的测试没有疏漏呢?
一些预示着设计存在这缺陷的特征:
过长的设置代码——如果为了一个简单的断言,需要花费上百行代码创建对象,那么肯定有哪儿不对劲儿。对象太大,需要分割。
冗余的设置代码——如果你无法为公共代码找到一个存放它的公共场所的话,那么就表明有太多的对象过于紧密地联系在一起了。
过长的测试运行时间——这样测试不会被经常运行,同时也暗示着对系统的方方面面进行测试是困难的。这种测试困难是一种设计问题,并且需要在设计时就被提出来。
脆弱的测试——意外中断的测试说明应用的某一部分出人意料地存在对另一部分的影响。你需要对系统进行设计,要么打破联系,要么将两部分合并,直到这种影响消失为止。
你需要多少反馈?
测试驱动的开发对测试的观点就是注重实效。在测试驱动开发中,测试从某种意义上说是一种达到目的的手段——达到充满自信地编写代码的目的。如果我们对实现有充分了解,不用测试就能拥有自信的话,那么就没有必要编写测试了。
什么时候应该删除测试?
如果删除一个测试降低了你对整个系统功能的信心,那么就不要删除。
如果你有两个测试,走的是同一条路,但对读者来说讲述的是不同的情形的话,那么就应该原封不动的保留。
如果有两个测试,它们就自信和沟通而言都是冗余的,那么就删除其中用处最小的那个。
如何中途转向测试驱动开发?
首先限定修改的范围。对于该范围外的可以简化的地方先不动手。
其次,必须打破测试与重构之间的僵局。可以先通过其他方式获取反馈,如系统测试,然后使用这些反馈进行修改。通过这种方式逐渐的让一直在改变的部分转向测试驱动。