浏览 2276 次
锁定老帖子 主题:大话重构连载12:你不能没有保险索
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2014-09-08
然而,这里有一个非常重要的假设条件,那就是“保证每一步都是正确的”,这是怎么保证的呢?就这个问题,我们需要展开来认真讨论讨论。 毫无疑问,系统重构就其结果来看,是在对软件系统进行大范围、大幅度的改动,而这种改动过去我们是无法想象的,因为它实在是改动太大了,一不小心就会产生一个毁灭性的结果。这就是许多人不敢轻易尝试系统重构的重要原因。 是的,这就是真相,如果你不能正确地验证每一步系统重构是否正确,或者你的验证方式存在缺陷,即使小步快跑也不能解决重构带来的风险。所以我们说,系统重构,你不能没有保险索。这个保险索就是每次重构后正确的测试方法。 什么是程序代码正确的测试方法,其在不同的场景中标准是不一样的。但与其它测试不同,系统重构在测试代码正确性方面却有自己独特的方法。系统重构,从自身的定义上就把其代码正确性的验证方式描述得十分明白,那就是“不改变软件外部行为”。 “不改变软件外部行为”,我们可以从多个层面上看待这个问题。首先从功能层面上看,重构前系统提供给用户什么样的功能,重构后也应当提供同样的功能。说得更加具体一些,重构前,用户从界面上输入什么内容,发出什么请求,得到什么结果,那么重构后用户应当得到同样的结果。这种结果可能体现在前端界面所展现的结果中,也可能体现在此处操作后存入数据库的数据中,即重构前后系统存入数据库的数据也应当是一致的。存入数据库的数据同样是测试中系统输出的一种。 从功能层面再往下钻就到了代码层面。打开我们的软件系统,有各个层次、各项接口和各种函数。我们进行系统重构往往是在某个层次、某项接口或某个函数上进行的重构。比如,我们对某项接口进行重构,那么我们可能会修改这个接口的实现类、方法函数、底层调用类,但不论怎么修改,这个接口必须保持不变。也就是说,我们代码层面的重构,“不改变软件外部行为”是针对的这个接口。你可以重构接口内部,但必须保证接口外部是不变的。 所以,系统重构的测试可以从两个层面来进行:系统测试与单元测试。系统测试往往是一种手工测试,当然也可以使用QTP等工具进行一些简单的录制。重构前我们首先通过需求文档确认系统现有功能,根据现有功能设计测试用例。然后进入系统,确保每个测试通过,并录制成QTP脚本。这样,我们对重构的准备工作就完成了。在整个测试过程中,我们每完成一次重构就去手工执行这些测试,或者执行QTP脚本,保证每个测试通过。如果测试不通过,则要么寻找问题原因并解决,要么就恢复到上次测试的版本,此次重构宣布失败。 反复地手工进行同样的测试是一件比较烦人的事,因此你可以有两个选择:录制QTP脚本,以及在接口层面建立自动化测试程序。这里所说的自动化测试程序是指那些基于JUnit编写的自动化测试程序,它实际上是在代码层面进行的单元测试。建立自动化测试的关键在于我们在哪个层面建立测试。代码有许多层次,有函数级别、有类级别、有接口或抽象类级别,从系统分层结构来说有底层、DAO层、BUS层、Web层。每次重构都是站在某个层次进行重构,因此自动化测试代码也应当在这个层次上写。比如最初的重构是在函数层次上进行的,就应当对函数写测试代码;后来在对象层次上进行重构,就对对象写测试代码;再到接口层次…… 与手工测试一样,在系统重构前,我们首先保证原有代码自动化测试通过。然后执行重构,保证每次重构都能够测试通过,如此往复。但重构中的自动化测试有一个问题就是,测试接口不太稳定。起初是在函数级别进行的重构,我们写了针对函数的测试代码。但随着重构的深入,我们开始在对象层面进行重构了,我们可能要调整原有的函数。这时将意味着原有的针对函数编写的测试代码将失效而必须要遗弃,这不得不说是一种浪费。因此我给大家的建议是,不要过早编写自动化测试代码,它不一定能节省我们的时间,甚至可能花费更多。最初的重构可以采用手工测试或QTP测试的方式进行。 大话重构连载首页:http://fangang.iteye.com/blog/2081995 特别说明:希望网友们在转载本文时,应当注明作者或出处,以示对作者的尊重,谢谢! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |