路是爬出来的

单元测试总篇与TTD实践

        经过前几篇的测试学习跟实践,我觉得有必要对这次学习做个总结。其实上面的话只是幌子,主要原因还是javaeye的

lighter 写道

貌似这一篇文章要放在"agile"版块更好一些吧.

btw:wuhua同学写文章有时候可以把两篇结合成一篇,可能会更好一些,不然让别人看一篇文章要看一,二,三,四才能看完.个人建议而已,别见怪.



觉得他说的很对,当时是出于篇幅过程,怕javaeye blog不支持大篇幅的文章,所以拆开。不过我觉得我这个担心是多余的。这里说句题外话,我用过很多Blog,但觉得这里是最好的。速度快,写文章贴心(主要是对源代码格式化方面做的很出色)。



好了,进入正题。

先介绍下我以前写的那些文章先,让大家对这篇文章有个初步的认识。

单元测试之测试目的,

单元测试之实践一,关于设计的常见分层

单元测试之实践二,关于DAO的测试

单元测试之实践三 Service的测试









单元测试之实践四 Action的测试



以前我正常的设计流程是Database->Model -> Dao-> Service -> Action ->View。这样的设计伴随我1年多了,这样的设计方式好吗?这样的设计高效吗? 代码质量能保证吗? 我可以很肯定的回答,不能,如果数据库一该,我要在表格里面添加一个字段,或者什么的。那么它将会牵连到很多其他,修改的动作如下:Database->Model -> Dao-> Service -> Action ->View。 噢,my got,几乎跟设计的一样多,甚至更多,因为在修改的过程中你就算有再好IDE去重构它也不能保证它的正确性。然后你就要去测试,测试它的正确性。也许测试的过程将是修改过程的几倍时间。所以我个人觉得这样的设计方式是不高效的。总而言之就是这样的设计迟早会出问题的?



为什么会这样呢?难道就没有一种解决办法吗? 经过这段日子学习我发现,以前的设计不能很好的保证质量是因为你没有足够的单元测试去支撑着它,所以你改了代码后缺乏一个很好的手段去保持这段代码的质量,换句话的意思就是,没有一个静态的人去监督你的工作(我把单元测试比喻为静态的人,它只做一件事,就是督促你的代码不出问题)。



好了。我们已经找到了适合保证我们代码质量的方法了。但是我们还得提高我们的开发效率啊。这又怎么办呢?是不是还按照以前的方式吗?我想自己浑浑噩噩的活了20多年了。我想换种活法了,想找种更刺激,更有意义的生活方式。

设计有时候更生活是一样的,应该经常探索,经常实践才能感受的更多。

那好吧我们就来个彻底的变革吧。怎么变呢? 很明显:那就是TDD。

该怎么做呢?

以前的方式:Database->Model -> Dao-> Service -> Action ->View。

TDD的方式:Test->其他。

先看看下面Dao的例子吧:以前的方式:IBaseDao ->  BaseDao -> BaseDaoTest。

TDD:BaseDaoTest->IBaseDao->BaseDao.


 


  1. public void testFindAccountByName(){  

  2.     Account a = new Account("wuhua");      

  3.     ht.find("from Account as a where a.name=?", a.getName());  

  4.     List l = new ArrayList();  

  5.     l.add(a);  

  6.     control.setReturnValue(l);  

  7.     control.replay();  

  8.     Account result =  accountDao.findAccounByName(a.getName());  

  9.     Assert.assertEquals(a.getId(),result.getId());  

  10.     Assert.assertEquals(a, result);  

  11.     control.verify();  

  12.       

  13. }  



好,非常好,怎么这段代码不能运行呢?当然不行了,因为上面的很多类都没有。那我们这段代码的用途是什么呢?

用途就是:以为上面的从上面的代码我很清楚自己以后要做什么。1,要建立一个Model,里面起码有一个name属性,然后你会发现我们要测试的功能段是accountDao.findAccounByName(a.getName()); 里面我们要求测试的SQL是from Account as a where a.name=?,意图明确吧。好,



我们写下实际代码吧。

java 代码



  1. public Account findAccounByName(String name) {  

  2.         List l = this.getHibernateTemplate().find("from Account as ", name);  

  3.         if(l != null && l.size() >=1)  

  4.             return (Account) l.get(0);  

  5.         else   

  6.             return null;  

  7.     }  



好,代码写好了。去运行我们的测试吧。结果是令人失望的。怎么会是红色的呢。肯定是逻辑代码出问题了(如果测试代码没问题的话)。经过检查发现原来
from Account as a where a.name=?跟from Account as 完全两码事。好改回去



java 代码


 


  1. public Account findAccounByName(String name) {  

  2.         List l = this.getHibernateTemplate().

  3.                              find("from Account as a where a.name=?", name);  

  4.         if(l != null && l.size() >=2)  

  5.             return (Account) l.get(0);  

  6.         else   

  7.             return null;  

  8.     } 



怎么还是红色啊。我不干了(程序员暴躁的情绪出来了,我就经常这样)主管跟我说:“再查查吧。别灰心。”

后来查了半天发现原来

java 代码


 


  1. List l = new ArrayList();    

  2.  l.add(a);   



我只renturn一个预期的对象a
java 代码


 


  1. if(l != null && l.size() >=2)  

  2.             return (Account) l.get(0);  

  3.         else   

  4.             return null;  



而代码却要求我要传入预期两个对象才给我通过,所以代码只return null。



最后改了这段代码

java 代码


 


  1. public Account findAccounByName(String name) {  

  2.         List l = this.getHibernateTemplate().find("from Account


  3.                                         as a where a.name=?", name);  

  4.         if(l != null && l.size() >=1)  

  5.             return (Account) l.get(0);  

  6.         else   

  7.             return null;  

  8.     }  





终于通过了。绿色,绿色,我看到了。我对主管说。主管笑了。我也笑了



最后我郁闷下,写这篇文章足足话了我22个小时,

第一次写好了。杀毒突然重启。所以全没了。

第二次,提交不了。然后忘记备份,又全没了

第三次成功了。过程跟TDD差不多。







posted on 2006-12-30 09:06 路是爬出来的 阅读(259) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航: