PTT推薦

Re: [討論] Unit test 的撰寫請益

看板Soft_Job標題Re: [討論] Unit test 的撰寫請益作者
GALINE
(天真可愛CQD)
時間推噓13 推:13 噓:0 →:4

※ 引述《shane87123 (陽光大肥宅)》之銘言:
先說在前面

雖然聽起來很幹話,但很多東西沒有標準答案
有時是合適度的問題,也可能是喜好(品味?)的問題

同一個題目,實際的 code 長得不一樣,可能也會用不同的方法處理


另外,除了資源豐富到人力充沛到不行的專案,以及幾乎沒有時程壓力
的專案(很多開源專案屬於後者),少有專案能把測試能做到真正完整

很多時候是取捨,花時間寫多少測試,能 cover 到最大的範圍
剩下的部分靠整合測試(包含自動與手動)來抓

經驗能讓人能更快做出效益更好的取捨

: 先說我對 Unit test 的看法:測試單元(可能是 function)的邏輯是否正確


: 常常會有一份 code 內其實呼叫了很多別份 code 的 function,
: 舉例來說
: A() {
: B();
: C();
: if (check)
: D();
: }

在「unit test」的前提之下,A() 這個「單元」要怎麼被定義?

- B() C() D() 的集合體?
- 負責分派邏輯前往 B() C() D() 的 router?
- A() 本身就做了一大堆事情,BCD 只是輔助?
- 其他?

在不同的狀況下,該測的單元功能會完全不一樣
適合的可能做法也完全不同


例如說對於狀況1
- 也許該把那個 if 檢查丟進 D(),讓 A() 就只是依序呼叫三個其他人的傳聲筒
接著不測 A() 但認真測 B() C() D()
- 沒有副作用可以,有副作用的話怎麼驗證副作用?


例如說對於狀況2
- 是不是該把 B / C / D 弄成變數傳進 A?
- 沒在寫 C 不知道 C 能怎麼做,function pointer?
- 或是有某種類似 router 定義的東西,然後測 router 功能?


例如說對於狀況3
- 全部 fake 是不是比較快?
- 是不是該把這個 function 拆掉?
- 誒,看到七層的 if else,真的覺得拆的掉嗎?
- 誒,看到七層的 if else,真的覺得要伴他一生一世嗎?

其實「重構」是個很常該被考慮的選項。
但當然,重構有時是個繁重的工作,也不見得是最常被選擇的選項


這也是 TDD 曾經風行一時的一部分原因,因為腦袋正常的工程師走 TDD
會避免自己寫出「啊,這要能測會把測試寫的有夠屎」的 code
但走 TDD 也可能寫出「看得懂想測什麼,但邏輯怎麼會這樣切」的東西



另外自己經驗是通常測試難寫是跟資料有關
「某些時候」如果非常辛苦的把資料 IO 全部 mock 一層,後面會好做一點
例如之前看過 api 專案平常線上是戳 MySQL 拿資料
在跑測試的時候直接開一個 in memory 的 sqlite 來當後端
測試邏輯會先把資料塞好好再來跑測試
於是就可以測「拿文章的時候會把內文特定 tag 換成其他 table 的資料」
之類資料連結度高的東西

走這條路的話不 fake 直接把邏輯跑完也是個好選項了
或者不用全部 fake,可以只 fake 幾個

這大概不算是「單元」測試吧
但該測的有測到,而且在艱苦的工程之後可以輕鬆往上疊一堆其他測試
(但..如果沒有那麼多東西要測,這會不會太厚工?)



另外不同程式語言(或不同輔助函式庫?)的狀況會天差地北
例如上面的 A(),如果是 python 的話可能可以不改 code
直接用 patch() 把 B() C() D() 變成 mocker,會回傳需要的值

測試就直接檢查 B/C 是不是每次都被呼叫到
D() 是不是條件對的時候有呼叫到

因為 mock 容易寫,全部 fake 掉會變成更有吸引力的選項




所以回到原本的題目:
全部 fake 跟全部不要 fake,選哪邊?


我的回答是:
這兩個都是選項,但不是只有這兩個選項。
例如重構,例如在其他地方準備抽象資料層,也都是選擇。
甚至手上的專案也可能變出不同的把戲。

這些都是能打的牌,要看場上環境怎樣,再來取捨該打哪幾張。



--
莉~娜~在~我~們~之~間~有~名~嗎~?

打倒了魔王大人,被那位大人附體之後平安無事地打倒了冥王大人
擊退了霸王大人,然後又打倒了魔王大人。

這種傢伙還不有名?魔族有那麼粗神經嗎?有那麼沒危機意識嗎?

--

※ PTT留言評論
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 218.166.60.66 (臺灣)
PTT 網址

hackfox11/09 14:50靠金燕,a.k.a姊姊

FatFatPig11/09 16:49推推

t6414111/09 16:56推,滿全面的分析

Burwei11/09 19:41

k7ji91ab5m11/09 19:58推 說得很好

markbex11/09 21:21推 敝單位也是視情況測"服務"或是測"單一元件"

viper970911/09 23:56推這篇

sssyoyo11/10 08:48

devilkool11/10 09:18推這篇

※ 編輯: GALINE (218.166.49.121 臺灣), 11/10/2022 11:02:45

strlen11/10 14:14我一直認為當初業界一堆在洗風向要寫測試的主因之一 就是

strlen11/10 14:15要利用測試來強迫大家做好封裝與架構分離

GALINE11/10 14:31也許喔,但 TDD 最大問題是寫測試的人通常不控制 spec...

NDark11/10 17:23就跟 product owner 其實不是真正能決定事情的人一樣

scottxxx66611/10 21:55

akitoex11/10 22:58

claymath11/11 00:20推一下

nec100211/15 15:12找本專業書籍k一下