其實(shí)軟件測(cè)試這件事情本身的難度一點(diǎn)都不亞于軟件開(kāi)發(fā),甚至可能更難一點(diǎn),常見(jiàn)的難題主要有以下這些。
1、測(cè)夠了嗎?
其實(shí)這是一個(gè)測(cè)試充分度的問(wèn)題。
代碼覆蓋率是衡量測(cè)試充分性的起點(diǎn),但遠(yuǎn)遠(yuǎn)不是終點(diǎn)。要回答”測(cè)夠了嗎“,至少還要考慮是否測(cè)了所有的場(chǎng)景、所有的狀態(tài)、所有的狀態(tài)轉(zhuǎn)移路徑、所有的事件序列、所有可能的配置、所有可能的數(shù)據(jù)等等等等。
即便如此,我們可能還是無(wú)法100 %確信我們已經(jīng)測(cè)夠了??赡芪覀冏罱K只能做到非常趨近于測(cè)夠了。
2、bug發(fā)現(xiàn)能力如何?
如何評(píng)價(jià)一組測(cè)試用例的發(fā)現(xiàn)bug的能力,屬于測(cè)試有效性的問(wèn)題。
評(píng)價(jià)測(cè)試用例有效性可以通過(guò)正向的分析進(jìn)行,例如,分析測(cè)試用例是否校驗(yàn)了所有在測(cè)試過(guò)程中SUT落庫(kù)的數(shù)據(jù)。更具有通用性的做法是變異測(cè)試(Mutation Testing),即在被測(cè)代碼里注入不同的“人造bug”,統(tǒng)計(jì)多少能被測(cè)試用例感知到。
3、哪些測(cè)試用例是在浪費(fèi)時(shí)間?
那么多用例,要花那么多時(shí)間去跑,這里面一定有很多時(shí)間是浪費(fèi)掉的,但如何才能知道哪些是浪費(fèi)掉的呢?
浪費(fèi)的形式包括:
冗余步驟:有些是浪費(fèi)在一些重復(fù)的步驟上,每個(gè)用例都要去做一些類似的數(shù)據(jù)準(zhǔn)備,每個(gè)用例都要去執(zhí)行一些中間過(guò)程。
等價(jià)類:一個(gè)支付場(chǎng)景,要不要在所有的國(guó)家、所有的幣種、所有的商戶、所有的支付渠道和卡組的排列組合都測(cè)一遍?這么測(cè),代價(jià)太高。有沒(méi)有更通用的、而且比較完備和可靠的等價(jià)類分析的技術(shù)手段?
有N個(gè)用例,推測(cè)這N個(gè)用例里面可能存在M個(gè)用例,即使刪掉這M個(gè)用例,剩下的N-M個(gè)用例的效果和之前N個(gè)用例的效果一樣。如何識(shí)別是否存在這樣的M個(gè)用例、如果存在的話是哪M個(gè)。
據(jù)說(shuō)阿里內(nèi)部職級(jí)晉升P9評(píng)審,曾經(jīng)就出現(xiàn)過(guò)“測(cè)試用例很多,你怎么刪”的問(wèn)題,看似簡(jiǎn)單,其實(shí)很難。
4、要不要做全鏈路回歸?
很多團(tuán)隊(duì)都會(huì)糾結(jié)到底要不要做全鏈路回歸、做到什么程度。
這個(gè)問(wèn)題的核心點(diǎn)就是:有沒(méi)有可能,只要把系統(tǒng)間的邊界約定的足夠好足夠完整,就可以做到在改動(dòng)一個(gè)系統(tǒng)的代碼后,不需要和上下游系統(tǒng)進(jìn)行集成測(cè)試,只要按照邊界約定驗(yàn)證好自己的代碼就可以確保沒(méi)有任何regression了。
很多人相信那是可能的,但既無(wú)法證明,也不敢在實(shí)操中就完全不跑集成。
5、如何減少分析遺漏?
分析遺漏是很多故障的原因。
開(kāi)發(fā)做系分的時(shí)候,有一個(gè)corner case沒(méi)考慮到、沒(méi)有處理。測(cè)試做測(cè)分的時(shí)候,忘記考慮某個(gè)特殊場(chǎng)景了。兼容性評(píng)估,評(píng)估下來(lái)沒(méi)有兼容性問(wèn)題的,但結(jié)果是有的。
而且很多時(shí)候,分析遺漏屬于unknown unknowns,我們壓根就不知道我們不知道。
6、用例自動(dòng)生成
Fuzz Test、Model Based Test、錄制回放、Traffic Bifurcation(引流)等都是自動(dòng)生成用例的手段。有些已經(jīng)比較成熟(例如單系統(tǒng)的錄制回放、引流),有些多個(gè)團(tuán)隊(duì)都在探索(例如Fuzz),有些則一直沒(méi)有大規(guī)模的成功實(shí)踐(例如MBT)。
7、問(wèn)題自動(dòng)排查
包括線上和線下。對(duì)于比較初級(jí)的問(wèn)題,自動(dòng)排查方案往往有兩個(gè)局限性。
首先,方案不夠通用,多多少少比較定制化。其次,比較依賴人工積累規(guī)則(說(shuō)的好聽(tīng)點(diǎn)叫“專家經(jīng)驗(yàn)”),主要是通過(guò)記錄和重復(fù)人肉排查的步驟來(lái)實(shí)現(xiàn)。然而,每個(gè)問(wèn)題都不完全一樣,問(wèn)題稍微一變,之前的排查步驟可能就不工作了。
8、缺陷自動(dòng)修復(fù)
阿里的Precfix、Facebook的SapFix等是目前比較知名的一些工業(yè)界的做法。但總的來(lái)說(shuō),現(xiàn)有的技術(shù)方案,都有這樣那樣的局限性和不足,這個(gè)領(lǐng)域還在相對(duì)早期階段,后面的路還很長(zhǎng)。
9、測(cè)試數(shù)據(jù)準(zhǔn)備如何提高效率?
測(cè)試用例的一個(gè)重要設(shè)計(jì)原則是:測(cè)試用例之間不應(yīng)該有依賴關(guān)系,一個(gè)測(cè)試用例的執(zhí)行結(jié)果不應(yīng)該受到其他測(cè)試用例的執(zhí)行結(jié)果(包括是否執(zhí)行)的影響。
但如果每個(gè)用例所需要用到的測(cè)試數(shù)據(jù)都是自己來(lái)從頭準(zhǔn)備的,執(zhí)行效率就比較低。怎么既不違背“測(cè)試用例之間不應(yīng)該有依賴關(guān)系”的大原則,又能減少測(cè)試數(shù)據(jù)的準(zhǔn)備時(shí)間?
10、兼容性測(cè)試
代碼和數(shù)據(jù)的兼容性問(wèn)題有很多形式。例如,如何確保新代碼能夠正確的處理所有的老數(shù)據(jù)?有時(shí)候,老數(shù)據(jù)是幾個(gè)月前的老代碼產(chǎn)生的,例如,一個(gè)正向支付單據(jù)可能會(huì)到幾個(gè)月以后才發(fā)生退款退票。
有時(shí)候,老數(shù)據(jù)可能就是幾分鐘前產(chǎn)生的:用戶的一個(gè)操作,背后的流程執(zhí)行到中間的時(shí)候代碼被升級(jí)了。
驗(yàn)證這些場(chǎng)景下的兼容性的難度在于:需要驗(yàn)證的可能性太多了。今天的退款請(qǐng)求對(duì)應(yīng)的正向單據(jù),可能是過(guò)去很多個(gè)版本的代碼產(chǎn)生的。一個(gè)業(yè)務(wù)流程執(zhí)行到中間具體什么地方代碼被升級(jí)了,可能性也非常多。
11、防錯(cuò)設(shè)計(jì)
嚴(yán)格來(lái)說(shuō),防錯(cuò)設(shè)計(jì)并不是software testing范疇內(nèi)的。
但做測(cè)試做久了就發(fā)現(xiàn),有很多bug、很多故障,如果設(shè)計(jì)的更好一點(diǎn),就壓根不會(huì)發(fā)生(因此也就談不上需要測(cè)試了)。