說來慚愧,和現在Comic Surfer Core的98%涵蓋率(Statement & branch coverage)相比,進公司到現在,我目前在寫的程式,搭配有單元測試的不多,主要有幾個原因,第一是Comic Surfer共121個測試案例,全部執行完畢平均不到2秒,這是讓我寫單元測試的動力,當一個測試要跑超過10秒,除非是超大系統的整合測試,我實在不想跑,也就自然不想寫了,現在光是一個小小的converter要測試,都要靠Spring framework注入一堆web services,10秒能啟動完整的環境就算是幸運了,即使那個method的測試案例可能不到0.1秒,但整體來說一個測試案例要跑10秒,啟動環境的時間是執行測試時間的100倍?光想就覺得煩...

  第二是如果不想靠Spring framework注入web services,那就寫mock的web services然後再用setter注入吧!事實上Spring framework也用類似的機制注入所需要的物件,但問題來了,以最近寫的converter為例,需要三個web services,也就是說我要一次mock三個web services,會用到這麼多web services是因為我們不直接跟DB溝通,都是透過web services,當初表格正規化的很徹底,而一張表格通常就對應了一個web service,在這樣的情況下,為了取得必要的資料,一個簡單的功能可能就需要多個web services,mock一個我還考慮考慮,mock二個我勉強勉強,mock三個我放棄,特別是公司用的mock framework,寫出來的mock不太能重複使用,我就不想寫mock了,最後還是透過Spring framework注入真的web service算了。

  第三是DAO的測試有點討厭,而且很難省時間,都是需要操作真正的DB,即便可以用In memory DB加快從硬碟讀取資料的速度,但Hibernate還是要靠Spring framework注入,因為transaction是由Spring framework來管,DB已經慢了,再加上Spring framework,唉...所以,另外一個同事以及架構師都說,測試都是丟到Jenkins上離線的時候跑,若當成regression test這idea很好,每天跑時時跑(我每天都會收到一堆Jenkins的報告),但單元測試的重點不就是快速反應錯誤然後快速修改嗎?目前Jenkins建置加上跑完所有測試案例超過半小時,我如果只是改一個小小地方,在Tomcat沒關掉,Eclipse plug-in會自動將程式更新到server的情況下,我還是寧願透過UI測試。

  再來是什麼該mock?最近使用公司內部一個系統的RESTful web service API,聽說我是第一個使用該API的人,可以想見,我完全變成bug reporter了,幾乎每一個我使用到的API都有問題(大概有八成吧),雖然負責那個API的人很友善,而且每次反應都會很快地建置一個新版的給我,但我有點納悶,有一次看到建置API時,他有執行單元測試,大概7、80個吧!不到10秒就全部跑完了,我想可能是因為區域網路吧!執行web service比較快,但為什麼我會遇到這麼多問題呢?於是我去看了他的測試案例,所有的response都是mock的,所以保證都不會錯,相信我,就算輸入是錯的,測試一樣會過,老實說response的內容才是驗證的重點,結果是mock的,我還能說什麼呢?特別是回到家時看到他發的感謝信,雖然明天又有新版的API可以用,但我有點無言。

  註1:我目前啟動server平均需要59秒,之前不知道誰改了什麼,server都會莫名其妙出現out of memory的exception,只好常常重新啟動server,為了那59秒,我還真的很想把硬碟換成SSD,不知道會不會快一點...所以,當有人看到我在FB的留言時,別懷疑,我應該是在等server啟動。

  註2:其實目前比較困擾我的是JavaScript的程式很不好測,最近的工作都是從前台一路寫到後台,然後再從前台一路測到後台,有時候最花時間的都是JavaScript...不知道其他寫web application的高人有什麼經驗能分享嗎?

創作者介紹

Spirit的異想世界

dbi1463 發表在 痞客邦 PIXNET 留言(0) 人氣()