技术开发 频道

如何才能保证测试代码的正确性

  四、每次写一点(原子级)测试

  这一点,其实说白了,是XP中的小增量迭代,测试驱动开发强调虽然是测试优先,但是测试开发并行过程中相互的交互作用是很关键的。

  一个很笼统的测试用例,既测试这个又测试那个,难免会复杂起来(量的积累带来质的变化),所以最好是一个测试用例只针对一个需求写测试,少量多次嘛。添加一点测试,运行失败,修改代码,运行测试,直到成功,然后重构代码,最后测试通过,是测试驱动开发的一个小迭代周期,当然迭代周期的控制是可以因人而异的。

  每次写的测试越少,那么表示你关注的问题或者需求就越少,那么精力就越集中,相对的测试的代码量也越少,大问题通常都可以通过将其拆分成多个小问题分别解决来得到解决,如果觉得测试代码太复杂,自然也可以通过拆分复杂的测试代码为多个小的相对简单的测试代码段来缩小其复杂性。

  五、Clean code that works,(当然包括测试代码啦,^_^)

  再好的设计,架不住你混乱的代码,最简单的,没有良好缩进格式的代码,看起来真是恶梦,现在工具这么好,都能自动化了,不过我还是能在工作中看到很多没有格式化好的代码,sigh,最起码的要求都做不到,更不要说让他去重构代码了,估计写测试也是没戏,TEST FIRST更是免谈了。

  所以别看这句话简单,做到了再体会才能理解。(这里又要唠叨下TEST FIRST,如前所述,我其实开始的时候是先写开发代码后写测试的,每次都很犹豫,是不是先写测试,而很多时候都架不住自己脑袋里那个已经“成型”的设计,要立刻写开发代码,测试嘛,总是认为后面再来也一样,不过在我多次逼自己先写测试之后,经历感觉完全不同,TEST FIRST根本不是原先自己所想的那样简单,所以,虽然我这里说了一堆它的好处,还是希望没有体验过的朋友别管那么多,试试先,一定会喜欢上它的,不过,要真正到处都使用它,还是要提高写测试代码水平的,因为测试代码不是那么简单哦,特别是和数据库和WEB搭上关系后)。

  好了,这一点,其实我也不用再详细说了,其实大家瞎子吃馄饨心里有数。至于怎么做到,嘿嘿,看看《测试驱动开发》吧,也许会有体会的,而我这里就超出范畴了,关于这点,我也就此打住,因为人大师的金玉良言更精辟更有说服力,我也不想在这里做转贴。

  六、对于一个应用框架,最好是针对这个框架先写一个测试框架(这其实是一个很具体的内容,不过现在JAVA在WEB方面用得很多,测试相对来说也比较难些,所以有这点)

  这一点是说到应用上了,^_^,其实也许这才是一些朋友希望交流的东西,因为开始我学写测试的时候,真不是我不想写啊,而是实在不知道怎么写,对一个复杂的应用,比如前端WEB,后台数据库,只要和这2者关联起来,再简单的需求写起测试来也是一大堆代码,有的甚至就根本不知道怎么测试。我现在也还是对数据库端的测试很惧怕,希望借此有朋友能讨论下。

  这里,我的观点是很明确的,一个应用框架,要有针对这个框架的测试框架来支持,才能让写出来的测试代码清晰以保证其正确性。测试框架的目的是要保证测试环境的正确搭建,这里说说题外话,测试环境,我认为是测试的关键,也是单元测试中最难的一个方面。对于一个接口的测试(纯粹的接口,不是实现类),可能就需要写一个扩展这个接口的实现类来辅助测试(我举的例子中,在开始考虑使用Decorator首先就是考虑的这个模式应用后的接口测试,这样我在测试具体的Decorator实现时才能抛开这个模式而单独测试实现类,而最后在column节点处理时用builder模式时,其实是拿默认的builder来做了这个测试的),这样做是我说的第二点;应用框架通常由接口架构,抽象出具体应用的接口,而具体应用则通过扩展该接口来实现功能,比如常见的WEB框架Structs,它的ACTION就是这样的接口,要做好对它的测试,框架本身的测试必不可少,但具体应用时其实和框架关系不大,只要制作符合要求的ACTION就可以了,这样的话,对ACTION的测试才是一般应用程序员要考虑的。对ACTION的测试,一种简单的方式是将ACTION中的要测试代码和STRUCTS框架隔离,这样就不需要访问STRUCTS框架,直接测试,但是,这样做其实不完整(不过这样做也有好处,就是将逻辑代码强制写在其它地方,而不写在ACTION中,当然ACTION本身就不是用来写这些的,不过我看到的,很多程序员其实是习惯于直接在ACTION中写业务逻辑代码的,这样的好处很少,就是眼前少写几行代码,但是以后就不见得了,这是我的第七点,大偷懒和小偷懒的区别),最好的状况是完整地测试ACTION类,从调用它开始,但是这样地话,准备测试环境会很麻烦,准备一个HTTP的REQUEST对象不是随便可以NEW出来的,会让人望而却步,要是只写一、二个这样的测试也就罢了,实际确实成百上千的,所以这个时候就需要一个测试框架了(呵呵,忽然想到,开始说测试框架,可能会有人误会,说是测试应用框架本身的代码,那样的测试当然不可少,不过这里说的测试框架,是指针对应用框架开发时要写的TESTCASE的框架),对于WEB测试有HTTPUNIT是不错的选择,不过还是比较低级的(呵呵,这里和语言一样的比喻,JAVA之类是高级语言,不是说它比汇编就高级),要针对STRUCTS框架写一个测试框架(现在有开源的这个框架),让测试环境的搭建工作简化到最少,这样真正写测试时才能只关注需求部分的测试代码,而测试代码本身也看起来不那么庞大。

  七、懒惰是程序员的通病,但是小偷懒就别了。(我有这样的观点:程序员的水平高低,其实从他偷懒的程度上是可以看出来的……^_^)

  第六点中已经带到了这个话题,其实只是调侃得说说自己的想法,不能算很正式的,因为这点其本质和测试没有一点关系。

  我很懒的,要不然不会选择这个职业,因为程序可以自动帮我做事,这样我就可以只是轻松地看着了,^_^。

  但是懒惰有很多种,有一种最直接的,只顾眼前的懒惰,还是拿不格式化代码来说,写的时候很随意,是好像让你少做了很多事,但是让看的人,让以后自己看的时候(特别是在查错时),付出更高的代价,我想,无论你在下次回头看这个代码的时候,理解它的时间是多花了多么少的时间,也比不上选个菜单自动格式化好代码花的时间少的。为变化而设计,正是为了将来能够更偷懒。有一个观点,现在我也想不起来是哪里看到了的,似乎哪里都有(《重构》啦、XP啦、测试驱动开发啦等等),就是在给一个已有模块添加新的功能前先重构已有代码,让已有代码适合于添加这个新的功能(好像第一次看到这个应该是《重构》一书),重构不是说让代码更好看而已,其目的就是为了适应变化,变化本来显得很大,但是可以通过重构来改善已有代码,让已有代码适合于新变化的添加,那么变化的复杂性就被缩小了。

  所以我说,小懒惰就免了,别影响大局,代码清晰、必要的重构,不作这些只是小懒惰,它们是以将来可能更大的付出为代价的。测试代码嘛,也只是代码而已。

  好了,终于写完了,中间几点难免有些雷同了(Clean code that works好像就可以涵盖所有了),还是总结下,思来想去,还是这句了:Clean code that works。大师的话就是精辟啊。不过,仔细想想,上面说的几点,好像都是没有说如何做到的,只是说了做到这几点可以极大得保证测试代码的正确性,但是这些关键点,要如何做到,我想大家还是多看看书吧,《测试驱动开发》、《重构》还有《极限编程-拥抱变化》这些都是难得的好书,我想,相对其它的书,这3本关键并不在于其有什么很高深的理论或者技术,而是它们都是指导程序员实践,如何从小处着手做程序,养成好的编程习惯,也更象是这些大师们自己手把手教咱写程序一样,难得的是文笔还很好,叙述得浅显易懂。

0
相关文章