

你就是寫太多測試才會沒時間(1):證明自己的清白
source link: https://teddy-chen-tw.blogspot.com/2023/06/1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

你就是寫太多測試才會沒時間(1):證明自己的清白
June 17 16:31~18:24
▲圖1:單元測試驗證修改過的email是否正確
前言
Teddy的朋友Kuma幾個月前寫了一本書:《你就是不寫測試才會沒時間:Kuma 的單元測試實戰 -- Java篇》。的確,自從Teddy在N年前開始寫第一個自動化單元測試之後,Teddy一直認為測試是開發不可分割的一部分。好的測試可以協助釐清規格、作為驗收條件、找出回歸錯誤,以及支持重構,讓開發人員走得更穩、更快。
但是,隨著測試案例越來越多,管理與重構這些測試案例就變成另一個頭痛的問題。下周二Teddy舉辦一個網路演講,講題是:「你就是寫太多測試才會沒時間」,就是要討論應對這種現象的方法。這個講題這雖然是一句帶有玩笑性質的話,但也代表對於測試看法的一種演進過程:
不寫測試沒時間 ---> 寫了測試有時間---> 累積太多欠管理的測試又變得沒時間 ---> 下階段是什麼?
針對這個主題,今天談一個單純一點的情況:如何簡單驗證待測程式沒有做它不該做的事情?
從範例看問題
軟體測試有一個基本原則:「除了要驗證待測程式做了該做的事情,也要驗證它沒有做不該做的事。」舉個例子,圖1中的User物件,呼叫它的changeEmail方法設定新的email,在第101行中驗證email是否被正確設定。這種測試很常見,但嚴格講起來這個測試並不完整。除了驗證email有被正確修改以外,還需要確保User物件的其他欄位沒有被改變。因為難保changeEmail的實作,除了改變email以外,會不會不小心動到User物件的其他欄位,例如把nickname清空。
但是,如果每一個測試案例都去驗證不應該被改動的欄位真的沒有被異動,將會增加很多測試工作,如圖2所示。
▲圖2:第104~109行驗證User除了email以外的其他欄位維持原狀
這還只是單元測試而已,如果是Use Case層次的測試案例,例如ChangeEmailUseCase,從Repository讀出User之後,理論上相同的assertion還要再寫一次。除了需要花費而外時間撰寫測試,也造成duplication code,增加日後維護測試案例的成本。
解決方案
先講結論,Teddy使用AssertJ這個「Fluent assertions for java」的測試工具來解決這個問題。圖3為Teddy使用ezSpec(Teddy自行開發的BDD工具軟體,可以直接用Java寫Given-When-Then,過一陣子會開源)所撰寫的ChangeEmailUseCase測試,第73行透過Repository從資料庫中拿出修改過email的User物件,然後第74行比對email欄位是否被正確修改。
接著在第76~78行使用AspectJ的assertThat做為比對物件的方式,呼叫usingRecursiveComparison,然後透過ignoringFieldsMatchingRegexes指定那些欄位不需要比對,最後再呼叫isEqualTo,就可以排除特定欄位之後,比對兩個物件是否相等。
圖3的程式範例擷取自ezKanban,由於ezKanban支援樂觀鎖,因此在每一個Aggregate物件身上都有一個version欄位用以作為樂觀鎖使用。因為User物件是一個Aggregate,所以User的email改變之後,version數值加1,因此在第77行比對修改前與修改後的兩個User物件實例是否相等的時候,除了排除email,也要排除version。
▲圖3:採用ezSpec撰寫的ChangeEmailUseCase測試
結論
透過工具幫忙,就可以用很簡潔的方式去確保物件的狀態。雖然Teddy在範例中使用AssertJ做為比對的工具,但相信不同的語言應該可以找到類似的工具。如果真的找不到怎麼辦?那就自己寫一個啊。
友藏內心獨白:開發人員就是要有Maker精神。
Recommend
-
9
.NET 彈性日期時間字串解析及小地雷 2021-01-30 08:06 AM 0 655 專案裡有個需求,希望當使用者輸入字串為日期或日期時間時自動轉成 DateTime 型別,我...
-
8
超越肉體、黑洞和時間:霍金(Stephen Hawking) – 余海峯 David此文章為立場邀稿,原文於 2018 年 3 月 16 日刊於
-
8
在 Azure 上建立虛擬機器(VM)的時候,有個 自動關機 (Auto-shutdown) 的功能可以非常便利的設定每天定時關機的時間,但是卻沒有 自動開機 的便利選項。今天這篇文章,我要來介紹一個超級簡單就可以設定完成...
-
7
列出 curl 連線的內部時間資訊 在 Twitter 上看到一個很久前的討論: https://t.co/GQF652CKkw
-
10
Nic Lin's Blog喜歡在地上滾的工程師速度快就像雷神降臨一樣帥當 Rails 專案逐漸成長之後,最令人頭痛的就是 Rails 的 boot time 實在是很久。有些沒辦法 reload o...
-
10
Nic Lin's Blog喜歡在地上滾的工程師有個需求是,對一個集合算出所有的數據中,兩個欄位的時間相減,取全部平均花費時間。# == Schema Information # # Table nam...
-
5
NOTE: 演算法的各種時間複雜度演算法時間複雜度分析:對每個不同的輸入大小,其基本運算所執行的次數 所有情況時間複雜度 T(n)T(n)
-
6
Heroku 公佈了廢止免費方案的時間表 打開 Hacker News 看到的第一名,
-
10
CPU Core 之間溝通的時間成本 在 Hacker News 上看到「
-
2
你就是寫太多測試才會沒時間(2):自動化測試是金字塔嗎? June 20 09:55~11:46
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK