經過前幾篇的測試學習跟實踐,我覺得有必要對這次學習做個總結。其實上面的話只是幌子,主要原因還是javaeye的
lighter 寫道
貌似這一篇文章要放在"agile"版塊更好一些吧.
btw:wuhua同學寫文章有時候可以把兩篇結合成一篇,可能會更好一些,不然讓別人看一篇文章要看一,二,三,四才能看完.個人建議而已,別見怪.
覺得他說的很對,當時是出于篇幅過程,怕javaeye blog不支持大篇幅的文章,所以拆開。不過我覺得我這個擔心是多余的。這里說句題外話,我用過很多Blog,但覺得這里是最好的。速度快,寫文章貼心(主要是對源代碼格式化方面做的很出色)。
好了,進入正題。
先介紹下我以前寫的那些文章先,讓大家對這篇文章有個初步的認識。
單元測試之測試目的,
單元測試之實踐一,關于設計的常見分層
單元測試之實踐二,關于DAO的測試
單元測試之實踐三 Service的測試
以前我正常的設計流程是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.
- public void testFindAccountByName(){
- Account a = new Account("wuhua");
- ht.find("from Account as a where a.name=?", a.getName());
- List l = new ArrayList();
- l.add(a);
- control.setReturnValue(l);
- control.replay();
- Account result = accountDao.findAccounByName(a.getName());
- Assert.assertEquals(a.getId(),result.getId());
- Assert.assertEquals(a, result);
- control.verify();
-
- }
好,非常好,怎么這段代碼不能運行呢?當然不行了,因為上面的很多類都沒有。那我們這段代碼的用途是什么呢?
用途就是:以為上面的從上面的代碼我很清楚自己以后要做什么。1,要建立一個Model,里面起碼有一個name屬性,然后你會發現我們要測試的功能段是 accountDao.findAccounByName(a.getName()); 里面我們要求測試的SQL是from Account as a where a.name=?,意圖明確吧。好,
我們寫下實際代碼吧。
java 代碼
- public Account findAccounByName(String name) {
- List l = this.getHibernateTemplate().find("from Account as ", name);
- if(l != null && l.size() >=1)
- return (Account) l.get(0);
- else
- return null;
- }
好,代碼寫好了。去運行我們的測試吧。結果是令人失望的。怎么會是紅色的呢。肯定是邏輯代碼出問題了(如果測試代碼沒問題的話)。經過檢查發現原來from Account as a where a.name=?跟from Account as 完全兩碼事。好改回去
java 代碼
- public Account findAccounByName(String name) {
- List l = this.getHibernateTemplate().
- find("from Account as a where a.name=?", name);
- if(l != null && l.size() >=2)
- return (Account) l.get(0);
- else
- return null;
- }
怎么還是紅色啊。我不干了(程序員暴躁的情緒出來了,我就經常這樣)主管跟我說:“再查查吧。別灰心。”
后來查了半天發現原來
java 代碼
- List l = new ArrayList();
- l.add(a);
我只renturn一個預期的對象a
java 代碼
- if(l != null && l.size() >=2)
- return (Account) l.get(0);
- else
- return null;
而代碼卻要求我要傳入預期兩個對象才給我通過,所以代碼只return null。
最后改了這段代碼
java 代碼
- public Account findAccounByName(String name) {
- List l = this.getHibernateTemplate().find("from Account
- as a where a.name=?", name);
- if(l != null && l.size() >=1)
- return (Account) l.get(0);
- else
- return null;
- }
終于通過了。綠色,綠色,我看到了。我對主管說。主管笑了。我也笑了
最后我郁悶下,寫這篇文章足足話了我22個小時,
第一次寫好了。殺毒突然重啟。所以全沒了。
第二次,提交不了。然后忘記備份,又全沒了
第三次成功了。過程跟TDD差不多。
|