單測(cè)無(wú)用論,這是真的嗎?
?大家好,我是樹哥!
工作了快 10 年了,跟研發(fā)小伙伴聊起單測(cè),絕大多數(shù)人的反應(yīng)是 —— 單測(cè)沒(méi)啥用,寫單測(cè)就是為了應(yīng)付單測(cè)覆蓋率的 KPI 指標(biāo)。恰好我最近在團(tuán)隊(duì)落地單測(cè)相關(guān)的內(nèi)容,經(jīng)過(guò)一段時(shí)間的持續(xù)迭代,我對(duì)單測(cè)的看法也從一開始的 沒(méi)啥用? 到后面的 好像有點(diǎn)東西?,再到最后的 臥槽,真牛逼!?;旧想S著單測(cè)寫得越深入,我對(duì)單測(cè)就越發(fā)重視。
為啥說(shuō)單測(cè)沒(méi)啥用?
那些說(shuō)單測(cè)沒(méi)啥用的小伙伴,我想大概率是不知道怎么寫單測(cè),沒(méi)寫過(guò)真正合格的單測(cè),而只是用單測(cè)來(lái)湊湊單測(cè)覆蓋率的 KPI 指標(biāo)。在這種情況下,單測(cè)當(dāng)然沒(méi)啥用,因?yàn)樗鼪](méi)辦法幫你提高代碼質(zhì)量,幫你減少 bug。
試想一下,如果一個(gè)東西能幫你提升需求開發(fā)質(zhì)量,減少提測(cè)需求 bug 數(shù)量,那研發(fā)同學(xué)怎么可能不愿意去學(xué)習(xí)一下呢?
在我看來(lái),單測(cè)一個(gè)很明顯的價(jià)值就是 —— 它能極大地減少你的需求 bug 數(shù)量,甚至一個(gè) bug 都沒(méi)有! 那為啥大家都會(huì)覺(jué)得單測(cè)沒(méi)用呢?我想問(wèn)題可能是多方面的,其中可能的幾個(gè)原因是:
- 需求不明確,邊寫代碼邊改需求,這咋寫單測(cè)?
- 時(shí)間非常趕,業(yè)務(wù)代碼都寫不完,還寫單測(cè)?
- 不知道咋寫單測(cè),于是隨便寫寫,發(fā)現(xiàn)好像沒(méi)啥用?
- 沒(méi)有選擇合適的單測(cè)框架,單測(cè)代碼寫的業(yè)務(wù)代碼還多,這可咋整?
- 等等
總而言之,這一切的原因?qū)е聸](méi)寫出合格的單測(cè),沒(méi)辦法讓單測(cè)為他們帶來(lái)好處,于是他們對(duì)單測(cè)充滿了失望,最終就覺(jué)得單測(cè)沒(méi)用。那怎么寫出合格的單測(cè)呢?這就是另外一個(gè)話題了,有機(jī)會(huì)我們?cè)僭敿?xì)聊聊。
單測(cè)到底有啥用?
聽我瞎扯了半天,有同學(xué)忍不住了:看你把單測(cè)吹得,那你說(shuō)單測(cè)到底有啥用?
在我看來(lái),單測(cè)除了顯著提升需求代碼質(zhì)量之外,還有下面幾個(gè)好處:
- 提升系統(tǒng)穩(wěn)定性
- 系統(tǒng)更加健壯
- 提升代碼編寫能力
- 有利于穩(wěn)定迭代
- 有利于深入了解技術(shù)與業(yè)務(wù)
提升系統(tǒng)穩(wěn)定性。 如果你每一個(gè)方法函數(shù)都經(jīng)過(guò)了測(cè)試,并且其分支覆蓋率都達(dá)到了較高水平,那么你很難寫出有問(wèn)題的代碼,因?yàn)槊糠N情況你都考慮到了。
在后續(xù)的迭代中,由于單測(cè)用例的存在,它就可以保證修改后的代碼不會(huì)影響到之前的業(yè)務(wù)邏輯。簡(jiǎn)單來(lái)說(shuō),由于單測(cè)的存在,違背之前業(yè)務(wù)邏輯的代碼無(wú)法運(yùn)行通過(guò),因此提高了系統(tǒng)穩(wěn)定性。
系統(tǒng)更加健壯。 系統(tǒng)的健壯,其實(shí)是得通過(guò)分支覆蓋率來(lái)實(shí)現(xiàn)的。分支覆蓋率,其實(shí)就是每一種可能的情況你都考慮到了,那么系統(tǒng)會(huì)更加健壯。
舉一個(gè)很簡(jiǎn)單的例子,有一個(gè)計(jì)算器類的除法函數(shù),簡(jiǎn)單的測(cè)試可能只會(huì)用正數(shù)進(jìn)行測(cè)試,更進(jìn)一步的可能會(huì)用負(fù)數(shù),但是如果用 0 去測(cè)試呢?是否能成功呢?通過(guò)對(duì)分支覆蓋率的要求,使得我們考慮到更多異常情況,從而使得系統(tǒng)更加健壯。
提升代碼編寫能力。 當(dāng)我們開始對(duì)單測(cè)覆蓋率和分支覆蓋率有要求,并且開始寫單測(cè)代碼之后,我們會(huì)被迫站在另一個(gè)視角去審視我們寫的代碼。如果我們的代碼寫得一點(diǎn)邏輯都沒(méi)有,那我們的單測(cè)會(huì)很難寫,那我們會(huì)忍不住去重寫它,這就間接地提升了我們的代碼編寫能力。
與代碼邏輯類似,代碼的結(jié)構(gòu)以及設(shè)計(jì)也會(huì)影響單測(cè)的編寫,寫單測(cè)可以讓我們重新審視自己寫的的代碼,從而間接提升我們的代碼編寫能力。
有利于穩(wěn)定迭代。 如果你寫的代碼質(zhì)量很高,只有非常少的 bug,甚至一個(gè) bug 都沒(méi)有。那么測(cè)你需求的測(cè)試肯定很開心,因?yàn)橹苯右话堰^(guò)呀!從項(xiàng)目管理層面來(lái)看,如果每個(gè)人都能做到這樣的程度,那么項(xiàng)目的迭代是非常穩(wěn)定、并且高效的!
有利于深入了解技術(shù)與業(yè)務(wù)。 當(dāng)我們寫單測(cè)的時(shí)候,我們必須去了解某個(gè)東西是怎么運(yùn)行的。如果你沒(méi)有了解清楚某塊業(yè)務(wù),就開始去修改這塊業(yè)務(wù)的代碼,那之前的單測(cè)用例會(huì)教你做人,頻頻報(bào)錯(cuò)的單測(cè)信息會(huì)讓你寸步難行。
單測(cè)用例的存在讓你必須弄清楚這塊業(yè)務(wù)的邏輯,才可以寫新的業(yè)務(wù)邏輯,這間接促進(jìn)了我們對(duì)于業(yè)務(wù)的了解。此外,我們寫單測(cè)的時(shí)候經(jīng)常會(huì)進(jìn)行 Stub 和 Mock,這會(huì)要求你必須弄清楚項(xiàng)目中用到的技術(shù)原理,不然你無(wú)法成功編寫單測(cè)代碼,這也同樣間接促進(jìn)你去了解項(xiàng)目中用到的技術(shù)。
單測(cè)不是銀彈
說(shuō)了這么多,可能有些小伙伴覺(jué)得我是單測(cè)的死忠粉。但我想說(shuō)的是:?jiǎn)螠y(cè)也不是銀彈!
在我看來(lái),單測(cè)只能解決一類問(wèn)題,那就是 —— 你覺(jué)得你寫對(duì)了,但是你沒(méi)寫對(duì)的問(wèn)題。 對(duì)于那些你本來(lái)就不知道,或者說(shuō)代碼里根本就沒(méi)寫的東西,單測(cè)是無(wú)能為力的。舉個(gè)很簡(jiǎn)單的幾個(gè)例子:
- 提測(cè)提了一個(gè) bug,你排查之后發(fā)現(xiàn)有某個(gè)業(yè)務(wù)細(xì)節(jié)你沒(méi)考慮到,從而觸發(fā)了這個(gè) bug。由于你本來(lái)就沒(méi)考慮到,因此代碼里也沒(méi)有做對(duì)應(yīng)的處理,那么單測(cè)肯定也解決不了這個(gè)問(wèn)題。
- 由于產(chǎn)品對(duì)需求沒(méi)有寫清楚,于是在測(cè)試階段不斷補(bǔ)需求細(xì)節(jié),于是你也不斷地修修改改,于是越改 bug 越多。
除此之外,寫單測(cè)也確實(shí)是會(huì)費(fèi)一些時(shí)間,特別是對(duì)于剛剛寫單測(cè)的同學(xué)來(lái)說(shuō)。如果一個(gè)項(xiàng)目非常緊張,需求也不確定,經(jīng)常邊寫代碼邊改需求,這時(shí)候再要求單測(cè)覆蓋率,可能不太現(xiàn)實(shí)。
單測(cè)的適用場(chǎng)景
看了這么多,知道了單測(cè)有那么多好處,但又單測(cè)又不能包治百病,那單測(cè)到底適合在什么場(chǎng)景使用呢?在我看來(lái),對(duì)于是否要推行單測(cè),以及單測(cè)的要求高低,其實(shí)取決于下面幾個(gè)維度:
- 代碼復(fù)用率。代碼復(fù)用率越高,越有必要推行單測(cè),越有必要提升單測(cè)的要求。因此這些代碼被很多業(yè)務(wù)引用,因此其一旦有問(wèn)題便會(huì)影響很多業(yè)務(wù)方,在這樣的代碼推行單測(cè)是收益較高的。
- 業(yè)務(wù)變化率。業(yè)務(wù)變化越快,越不適合用單測(cè)。如果業(yè)務(wù)變化非???,一個(gè)單測(cè)的內(nèi)容上線了沒(méi)幾天就又要修改,那么你不僅僅需要修改業(yè)務(wù)代碼,還需要修改單測(cè)代碼,那就是雙倍的工作量了。
- 人員變化率。人員變化率指的是某個(gè)模塊負(fù)責(zé)人的變化情況。如果某個(gè)模塊的負(fù)責(zé)人經(jīng)常變來(lái)變?nèi)?,那么也是不太適合推行單測(cè)的。因?yàn)樾仑?fù)責(zé)的人需要花大量的時(shí)間去熟悉單測(cè)的內(nèi)容,這會(huì)導(dǎo)致需求開發(fā)的時(shí)間變得非常長(zhǎng)。
- 業(yè)務(wù)重要性。越是核心的業(yè)務(wù),越有必要推行單測(cè),并且越有必要以高標(biāo)準(zhǔn)要求。因?yàn)楹诵臉I(yè)務(wù)的穩(wěn)定性、健壯性對(duì)于公司來(lái)說(shuō)肯定非常重要,而單測(cè)確實(shí)是能夠在最小單元去提升系統(tǒng)穩(wěn)定性和系統(tǒng)健壯性。
上面提到的 4 個(gè)衡量維度,我們不能單一地去看待,而是要根據(jù)實(shí)際情況去綜合判斷。例如某個(gè)業(yè)務(wù)的人員變化就是很頻繁,那就一定不適合推行單測(cè)嗎?
其實(shí)并不是,而是說(shuō)對(duì)于人員變化非常頻繁的業(yè)務(wù),其推行單測(cè)成本會(huì)很高。但如果這塊業(yè)務(wù)就是非常重要,但他的人員變化就是很頻繁,那強(qiáng)制以高標(biāo)準(zhǔn)的單測(cè)要求確實(shí)可以提高系統(tǒng)健壯性和系統(tǒng)穩(wěn)定性,但是代價(jià)就是研發(fā)時(shí)間很長(zhǎng)。如果產(chǎn)研團(tuán)隊(duì)能夠接受這個(gè)結(jié)果,那么這么做就是合理的。
總的來(lái)看,是否推行單測(cè)以及推行單測(cè)的標(biāo)準(zhǔn)高低,需要我們根據(jù)上面幾個(gè)維度去綜合考量,得出一個(gè)最適合的標(biāo)準(zhǔn)!?