Re: [討論] 工作上寫單元測試的比例
※ 引述《langrisser19 (lan)》之銘言:
: 總之每個方式都有一些共用,或是非共用的行為
: 目前的程式像這樣
: func 儲值(方式){
: switch 方式{
: case 方式1:
: if 符合條件1 {
: if 符合條件2 {
: if 呼叫api-1 成功{
: 更新介面1
: }
: }
: }
: case 方式2:
: 要符合不同的巢狀條件,然後呼叫另一隻api,一樣根據結果更新不同的介面: case 方式3:
: 又是不同的條件跟api
: }
: }
: 像這樣的程式,不知道測試怎麼寫?
ㄅ是啊,你應該是先有需求才有測試,
通常是先假設已經在線上的已經經過線上考驗。
如果沒有這種需求,你根本就不應該整理。
我個人認為任何在沒有需求的前提下情況下整理程式碼,
是一個浪費自己時間又沒意義的行為。
有需求,你就會相對清楚你要處理的邊界在哪,
而不是在思考我要處理多寬的問題。
比方說,今天是要修方式3裡面的某算式好了好了。
那就是先用重構工具把 //又是不同的條件跟 api 的部分抽出函示,
然後把 member 成員的部分都轉成 input 。
(這是我的作法啦,這算是應急的第一步,
這個可以再透過重構的推跟拉來把他攤成 module,
但假設今天的情況是比較快的模式。)
xxx(){
......
switch(xxx){
......
case 方式3:
方式3_implement(xxx,yyy,zzz);
}
}
public static 方式3Response 方式3_implement(xxx,yyy,zzz){
//又是不同的條件跟api
}
Test case:
public class 方式3TestCase{
public void Test方式3(){
var mockxxx="xxx", mockyyy="yyy", mockzzz="zzz";
var res = xxx.方式3_implement(mockxxx,mockyyy,mockzzz);
方式3Response.aaa.should().be(xxx);
}
}
通常我會先把「已經存在的案例」先寫成測資,
因為老話一句,改前改後都要對的東西可以當對照組。
========
通常以上在有正常重構工具的情況應該是幾秒鐘的事情,
沒有的話就是自己搬變數比較煩,應該也是十幾分鐘要能搞定。
這裡可能會有一個例外,就是方式3 如果沒有明確可驗證的回傳值,
(也就是 void )
這時候我自己習慣的是,自己根據重要的地方補 true/false 的 bool,
只驗這個必要的 bool,這就要花點技巧處理的地方。
總之你要有「可驗證點」,這是可驗證性中很重要的一環。
然後考慮到可驗證點,你一開始就把「所有方式」,
寫成一個大 test case 講白了只是在找自己麻煩。
你完全沒有必要去做一個這麼難的 normalize,除非結構真的超級漂亮。
我會說你原文作的事情,其實是蠻 anti pattern 的,
真實世界中往往80%以上的情況是帶不進去的。XD
會做到一半發現當初分開是有理由的,然後又走回起點。
我的習慣就是方式1做到寫一個 方式2做到寫一個,
起碼當我需要測試的時候,我有一個子點。
然後不會強求展開,就是「有發生問題的補」、「懷疑會發生問題的補」,
你沒有無窮的時間窮舉,所以問題永遠是限縮跟抽樣。
必要的時候我會把我不關心的選項直接寫成 if(xxx) throw new exception();
表示此路不通,來減少子支。
========
再來是推進 方式3_implement 的開發。
這時候我會評估一下 方式3_implement 的複雜度,
如果很大而且很難肉眼比對的話,我會複製一個
方式3v2_implement ,內容跟方式3_implement 一樣。
然後稍微調整 Test case:
public class 方式3TestCase{
public void Test方式3(){
//因為是static 所以可以呼叫,
//這裡可能會需要 visible to internal 或暫時開成public var res = xxx.方式3_implement(mockxxx,mockyyy,mockzzz);
res.aaa.should().be(xxx);
var res2 = xxx.方式3v2_implement(mockxxx,mockyyy,mockzzz);
res2.aaa.should().be(res.aaa);
//這是為了避免自己腦殘,當然這樣改的前提是 input/output ,
//新舊一致的情況,通常都會有重疊場景,如果沒有就不用這麼做。
}
}
接著就開始從 方式3v2_implement 下寫新的實作,
然後反覆跑 Test方式3 ,然後看狀況加新的 test method ,補新的測資跟場景。
這裡的前提是無副作用,有副作用的就都得透過 mock 先把副作用的影響處理掉,
大多數的時間會花在研究副作用跟子類。(其實就是讀code)
就這樣而已,沒什麼 magic,
你想改哪,就只縮哪。
另外原本的 v1 雖然看起來是重複代碼,但是過一兩個週期就可以回頭刪除他了,
而且因為他照理說會除了 test 以外沒被連結又是新增程式,
對實際的程式基本上影響為0。
然後你會問我,那你原本想幹的方式1,2,3,4,5能不能整併,
施主這要看你的需求。
通常我的習慣是上面的方式3Response,我會試著帶進去看看,
方式3方式2能不能共用回傳值。
如果可以,那才有談的空間,沒有的話,該分歧就分歧,不要亂合。
然後至於假設在方式1,2,3,4,5 還有 token驗證之類的上游問題,
那就是另外寫 test ,我這個 test 只涵蓋這個下游情境。
用「限縮環境」來減少你一次要看的範圍,
強化你對局部開發的速度跟掌握力,也是可測試性中很重要的一環。
--
感謝分享
最重要需求不要三心二意xdddd
需求三心二意就是跟著最後一次的需求走,你有寫TEST也比較
理解哪些是破壞性的需求,哪些是延伸性(不破壞既有條件)y
的需求
因為不管需求如何變化,你都得確認最後的那個版本你寫的是
對的
然後可測試性高的程式碼,你會有比較多端點可以抽換。
推這篇實際
請公司多聘SDET $$$$$ QAQ
我的認知是整個project除了main method這個進入點不用
寫到UT,其他的所有method都要被至少一支UT程式跑到過
,包含static的method
這就是追求 coverage ,但實際上沒這回事啦, 多數專案自己能做到30% coverage 就很了不起了。 提這個概念只是跟自己的時間過不去而已。
推一個
當你一開始才0%coverage開始的時候,最重要的先做
41
首Po想請問一下 大家工作上寫單元測試的情況 1.大部分寫完一個功能, 就馬上完成單元測試 2.先把該做的功能寫完, 再回來統一寫單元測試 3.不怎麼寫單元測試5
你講的三種我都做過,還有第四種:TDD 1. TAD,講白了就是先射箭再畫靶,如果你箭射對了那當然沒問題 但如果你一開始就射錯了還忘記拔出來,就是無效的測試 2. 同樣也是TAD,這個是我們被要求做的,code不是我們寫的、但我 們要幫其他team補測試。我主管也覺得很奇怪、我也覺得很奇怪,3
我覺得命題不是寫/不寫。 真的該問的是,工作上 reviewer 也好、或者是開發流程也好, 有沒有辦法【正常的判斷】 test 是不是寫對的。 XD 起碼是 team 能有一定認同的前提。 其實最後都回到 quality check,不然只是繞圈圈而已。 XD17
我想補一個情境 當到新公司或轉到新單位時 發現沒有在做unit test 此時身經百戰寫過上千次unit test的你 會選擇憑一己之力6
底下這是比較「野性」」的作法,算是實務專案的經驗: 其實我覺得你到一個完全沒有測試的專案,要分兩個策略: 1. 補重要主線的 integration test 反正哪邊常被報修就補哪邊。 如果一開始補不上去就先做下一點,理論上常被報修的地方會一直出現在下一點, 累積多了就可以變成1了。1
先說我不是故意要回兩篇, 但剛看到 landlord (就 joey chen, 江湖名 91) 在 FB 的回應,我覺得也蠻好的, 他說他最近在忙沒空過來,我問過他之後幫他轉過來。 以下基本上逐字照轉 (source from )2
因為大家的討論都很基於心法 實作上相對很模糊 利用這個機會也跟大家請教實作上的方式 因為最近工作被指派要針對公司產品的程式做整理,其實運作都還好 只是大家功能是一層疊一層,一堆巢狀邏輯,跟依賴中的依賴2
原則上要寫測試的話我會用很古老的 TDD 的方式做,先寫測試之後再寫實作。 現在的話則是寫完測試之後 Copilot 就幫我寫完一半了,然後就開始 review copilot 的 code 了。 目前經驗上能不能寫測試的話我認為有三個維度會是主要影響關鍵,提供參考: 1. 文件是否齊全16
分享最近遇到的鬼故事 當初開發完A功能後有順手寫了UT確保該功能基本能動 後來有同事在開發B功能時把他的B功能加進去我的UT default flow內 也沒有請我code review 導致我在跑UT時發現不預期的行為
49
Re: [討論] 這樣能進入軟體業嗎??: 簡單的幫你review一下 一般而言,面試官很忙的,所以會沒時間去把你的code拿下來build過在安裝 所以如果你覺得寫得很好的話,建議直接放上google play這樣面試官有機會把玩 然後我看code是有一定質量,所以junior的碼農缺基本上是沒啥問題的39
Re: [心得] (轉)軟體開發六年後我改變想法的事情這篇滿有意思的,牽涉的主題很廣,不過有些事情只有一句很難講清楚 針對中間幾點,分享一些我自己的理解 ※ 引述《alihue (wanda wanda)》之銘言: : 看到不錯的文章 翻譯分享一下 : 原文:33
Re: [討論] Unit test 的撰寫請益先說結論,先都不要寫。 Legacy system 要先補大範圍的 integration test,確定整體的行為是對的。 如果 code 沒有要再改,不用補細部 unit tests。 原因是因為,原本 API 可能因為設計不良,導致無法寫 unit test 得先 refactor 才有辦法讓它變成 testable,這情況就要先 refactor 再補 UT23
Re: [討論] 怎樣算是一個合格的junior cpp programme針對關於 TDD 的討論另外回一篇好了 覺得用推文太長了 XD : 推 stupidlove0: 朝聖!重要的真的是unit test 08/23 18:47 : → HZYSoft: 回樓上 TDD 問題,TDD 不只要測試,還要先寫測試才寫code 08/23 21:33 : → HZYSoft: 很多人無法習慣這種順序,是否一定要 TDD 這有爭議 08/23 21:3416
[討論] Unit test 的撰寫請益先說我對 Unit test 的看法:測試單元(可能是 function)的邏輯是否正確 好,進入正題 小弟最近剛工作,稍微讀了一下負責的 project 的程式碼後, 要開始開發 Unit test。 現況是,各個 file (.c) dependency 很重,15
Re: [請益] 這種情況要怎麼重構我這篇寫的跟原原PO的狀況無關 ※ 引述《tbpfs ( )》之銘言: : 其實我真的不懂為什麼要急著重構 : 有好處嗎? : 一般而言,重構都是發生在農閒的時候11
[問卦] 河內塔是誰想出來的?只有三根柱子的河內塔 若有64個盤子 需要 2^64 - 1 步才能搬完 如果一秒搬一塊 從宇宙開始搬到現在都還沒搬完3
Re: [閒聊] ChatGPT是語言模型不是搜尋引擎這個敘述也太強烈了吧? StackOverflow 上面不是只有 code template,重要的是有很多的討論和推論。 而且如果有新的library出來,很多人也會在StackOverflow上討論 關於這個議題,我來分享我最近遇到的案例 最近在工作上寫code遇到一個問題是,我發現,1
Re: [討論] 怎樣算是一個合格的junior cpp programme關於 TDD 個人一點看法 我覺得 TDD 最大的用處是讓你 "做一下,想一下", 這件事本身就很有用,相信有不少人有類似經驗, 很快想到一個版本,在幾個循環後陸續想到 3~5 個改版, 其中則有某個版本特別好實作,可以用初版 1/5 以下的時間完成,