本文仅就单元测试而论,虽然是说的测试,但目的是驱动开发,不过也不是谈测试驱动开发,更象是对测试驱动开发时TEST FIRST这个过程中如何保证测试代码的正确性的理解和想法,当然有一些,我认为是通用的,不管是不是测试优先。而我目前接触最多的还是JAVA的单元测试,所以谈的东西还是以JAVA为主,举的例子都是和JAVA有关的。
另外前些天看到一个帖子有人问这样的问题,想到当初自己刚接触JUNIT单元测试时也有类似的困惑,现在有了一些经验,所以写下来,既是对自己经验的总结,也是希望能有人相互讨论提高。
首先是我认为要做到测试代码的正确性的几个要点:
一、TEST FIRST
二、只写出需求测试(注意,是目标代码需求,这个代码的用户当然是自己了,^_^)
三、不要为了测试而测试(这句话是和一个朋友聊天时他说是他和Kent Back交流时Kent Back提醒他的,这里我也不是很确定对这句话的理解的正确与否,因为理解一句话,上下文也是关键的,而我并不很了解我朋友同Kent Back谈话的具体内容和过程,不过这里还是作为一个要点谈谈自己的想法)
四、每次写一点(原子级)测试
五、Clean code that works,(当然包括测试代码啦,^_^)
六、对于一个应用框架,最好是针对这个框架先写一个测试框架(这其实是一个很具体的内容,不过现在JAVA在WEB方面用得很多,测试相对来说也比较难些,所以有这点)
七、时刻提醒自己TEST FIRST的目的。(我们的目的是驱动开发,而不是为了测试,呵呵,这点是前面第一点和第二点和起来一样,之所以还要单独列,只是再次提醒,所以这一点我后面不作详细阐述)
八、偷懒是程序员的通病,但是小偷懒就别了。(我有这样的观点:程序员的水平高低,其实从他偷懒的程度上是可以看出来的……^_^)
在开始具体来说上述要点之前,我想先写个例子,只是觉得应该写个例子,^_^,我的文采实在不是很好的,所以凭感觉的。
一个例子:
我有一个专门用于将数据库操作结果集(ResultSet)解析成一个DOM的Document对象的类,这个类可以根据给定一个XML配置模板中的一个定义节点(declare节点)的子节点(column节点)集合来解析ResultSet生成Document对象,其中每个column节点都定义了要从ResultSet中获取的某一个字段的属性,包括字段名、该字段在展示是是否可修改(editable)、是否有格式化模式属性(pattern)用于格式化该字段的数据等等;为了做得更通用,也可以依据ResultSet返回的ResultSetMetaData对象来生成column节点,再由column节点获取数据体,当然这样做有很大的局限性,比如该column节点的pattern、editable等等属性的设置都不会太灵活。这个设计,其最大的灵活性被放在XML配置模板上,由模板的定义获取数据,并且定义了数据的展示属性,而一旦column节点是根据给定的ResultSet来自动生成时,灵活性大大折扣,虽然在大多数应用中,都不会使用由ResultSet来自动生成,但是如果一开始并不能确定定义列时却是必须这样做,特别是在ResultSet输出的字段数量是变化的时候。问题终于出来了,最近有一个应用就是这样,首先是必须要使用从ResultSet获取定义节点(column),然后,在完成了所有的代码后,发现给定ResultSet中都存在冗余字段,这个时候,没办法,只能是修改程序来适应它了。