分析Bug的維度
作者 | 常雨桐
在軟件開(kāi)發(fā)交付過(guò)程中,難免會(huì)出現(xiàn)Bug。針對(duì)每一個(gè)已發(fā)現(xiàn)問(wèn)題的Bug,完成修復(fù)工作后,我們可以對(duì)其進(jìn)行全面的根本原因分析。本文從測(cè)試人員的角度,嘗試梳理出一些常見(jiàn)的Bug根本原因分析的維度,并列舉每個(gè)維度中的根本原因的例子。
一、Bug分析的維度
建議盡量用便于統(tǒng)計(jì)和維護(hù)的方式,記錄分析的結(jié)果(比如使用Jira系統(tǒng)提供的label功能,下文中括號(hào)內(nèi)的英文是可參考的label名稱(chēng)),以便周期性地進(jìn)行全面的Bug分析。
每個(gè)Bug常見(jiàn)的可用于分析的根因維度如下:
1.Bug發(fā)現(xiàn)的環(huán)境 (Env)
(1) 維度定義:
描述該Bug是在什么環(huán)境中被測(cè)試人員/開(kāi)發(fā)團(tuán)隊(duì)成員/客戶(hù)/用戶(hù)發(fā)現(xiàn)的。
(2) 分析目的:
正常來(lái)講軟件開(kāi)發(fā)過(guò)程中,越早發(fā)現(xiàn)問(wèn)題,修復(fù)問(wèn)題所需要的成本也就越小。為此,需要關(guān)注開(kāi)發(fā)過(guò)程中的問(wèn)題是否可以在早期被發(fā)現(xiàn)。
分析此維度可以評(píng)估現(xiàn)在項(xiàng)目的Bug發(fā)現(xiàn)時(shí)機(jī)。制定針對(duì)性的改進(jìn)措施,以保證Bug可以被盡早發(fā)現(xiàn)。
(3) 維度示例:
各個(gè)項(xiàng)目所擁有的測(cè)試環(huán)境并不相同,請(qǐng)根據(jù)實(shí)際情況來(lái)進(jìn)行分類(lèi)。
- 開(kāi)發(fā)環(huán)境/測(cè)試環(huán)境 (參考Label名:Env_QA / Env_DEV) 。項(xiàng)目人員最常接觸的環(huán)境,也是鏈條最前端的環(huán)境。大部分的Bug應(yīng)該在此被發(fā)現(xiàn)。
- 集成環(huán)境(Env_Integration) 。常用于連接到外部或其他團(tuán)隊(duì)系統(tǒng)的環(huán)境,容易發(fā)現(xiàn)外部集成相關(guān)的Bug。
- 用戶(hù)驗(yàn)收環(huán)境 / 預(yù)發(fā)布環(huán)境(Env_UAT / Env_Pre-release / Env_Rehearsal) 。客戶(hù)對(duì)交付的系統(tǒng)做驗(yàn)收測(cè)試或上線(xiàn)前演練/回歸用的環(huán)境,數(shù)據(jù)和環(huán)境配置都會(huì)更貼近生產(chǎn)環(huán)境。
- 生產(chǎn)環(huán)境 (Env_Production) 。真正提供給線(xiàn)上用戶(hù)的環(huán)境,生產(chǎn)環(huán)境發(fā)現(xiàn)的Bug擁有較高的處理優(yōu)先級(jí)。
2.Bug引入時(shí)機(jī) (Timing)
(1) 維度定義:
描述引發(fā)該Bug的代碼/配置是在什么時(shí)機(jī)或者什么活動(dòng)中被引入到產(chǎn)品中的。
(2) 分析目的:
通過(guò)分析Bug的引入時(shí)機(jī),有機(jī)會(huì)識(shí)別出質(zhì)量保證體系中薄弱的點(diǎn),或團(tuán)隊(duì)在開(kāi)發(fā)/測(cè)試流程中的問(wèn)題。
(3) 維度示例:
常見(jiàn)的引入時(shí)機(jī)如下:
- 開(kāi)發(fā)新需求時(shí)產(chǎn)生的新功能的Bug(Timing_Developing_New_Requirement)。在開(kāi)發(fā)新功能時(shí),產(chǎn)生的新功能中的行為與需求不符的問(wèn)題。
- 開(kāi)發(fā)新需求時(shí)破壞原有功能 (Timing_Developing_Other_Requirement) 。在開(kāi)發(fā)新功能時(shí),破壞了原有的已驗(yàn)收過(guò)的功能的正確行為。
- 修復(fù)Bug破壞原有功能(Timing_Fix_Bug)。在修復(fù)其他Bug時(shí),引入了新Bug。
- 重構(gòu)破壞原有功能(Timing_Refoctor)。在對(duì)代碼進(jìn)行重構(gòu)的過(guò)程中,導(dǎo)致原有功能被破壞。雖然正常來(lái)講重構(gòu)活動(dòng)是會(huì)在開(kāi)發(fā)新卡時(shí)一起進(jìn)行,理應(yīng)分在開(kāi)發(fā)新功能時(shí)機(jī),但是考慮到重構(gòu)行為的特殊性,以及為了后期分析重構(gòu)時(shí)是否有足夠的自動(dòng)化測(cè)試保證原功能正常工作??梢砸暻闆r把重構(gòu)單獨(dú)作為一個(gè)引入時(shí)機(jī)進(jìn)行分析。
- 前人代碼遺留的Bug(Timing_Legacy_Issue)。中途接手的項(xiàng)目,在團(tuán)隊(duì)入場(chǎng)前就存在的問(wèn)題。或者超出目前項(xiàng)目預(yù)期范圍的原有問(wèn)題。一般PM會(huì)更加關(guān)注此類(lèi)問(wèn)題,以防團(tuán)隊(duì)為遺留問(wèn)題花費(fèi)太多effort,影響正常工作的展開(kāi)和新需求的交付進(jìn)度。
- 部署環(huán)境或運(yùn)行腳本(Timing_Env_Deployment_or_Script)。在部署/配置環(huán)境過(guò)程中引發(fā)的問(wèn)題,或直接操作數(shù)據(jù)庫(kù)數(shù)據(jù)引發(fā)的問(wèn)題。
- 不屬于Bug(Timing_Not_Bug) 。有時(shí)會(huì)發(fā)現(xiàn)該問(wèn)題不屬于Bug,本文后面會(huì)詳細(xì)敘述這種情況。
3.Bug所屬的前后端/微服務(wù)/功能模塊
(1) 維度定義:
描述該Bug的代碼問(wèn)題出現(xiàn)在前后端/微服務(wù)/功能模塊。
(2) 分析目的:
統(tǒng)計(jì)前后端/微服務(wù)/功能模塊的Bug比例分布,后續(xù)可以有針對(duì)性地進(jìn)行補(bǔ)充自動(dòng)化測(cè)試及分配測(cè)試資源。
(3) 維度示例:
各個(gè)項(xiàng)目所擁有的前后端并不相同,可以根據(jù)實(shí)際情況來(lái)進(jìn)行分類(lèi)。
4.Bug產(chǎn)生的直接代碼原因 (Root Cause)
(1) 維度定義:
描述引發(fā)該Bug的代碼的問(wèn)題,可以與開(kāi)發(fā)人員合作來(lái)分析。
(2) 分析目的:
結(jié)合下一個(gè)維度,評(píng)估團(tuán)隊(duì)人員上下文以及技術(shù)的掌握情況。通過(guò)進(jìn)行session/文檔同步上下文的方式進(jìn)行查漏補(bǔ)缺。
(3) 維度示例:
- 代碼業(yè)務(wù)邏輯錯(cuò)誤 (RC_wrong_bussiness_logic) 。代碼實(shí)現(xiàn)時(shí)對(duì)業(yè)務(wù)的錯(cuò)誤理解或者遺漏,導(dǎo)致了代碼邏輯跟業(yè)務(wù)邏輯不一致。
- 代碼邊界條件/Edge case未覆蓋 (RC_uncovered_edge_case) 。代碼實(shí)現(xiàn)時(shí)遺漏了某些業(yè)務(wù)場(chǎng)景/遺漏了對(duì)某些接口或函數(shù)的特殊返回值的處理。
- 框架或依賴(lài)功能/接口的錯(cuò)誤使用 (RC_wrongly_use_dependency)。代碼實(shí)現(xiàn)時(shí)使用了現(xiàn)有的函數(shù),或者其他微服務(wù)提供的接口。但是對(duì)其 業(yè)務(wù)含義/調(diào)用方法/返回處理 理解有誤導(dǎo)致的問(wèn)題。
- 踩了使用的框架或依賴(lài)的原有的坑/技術(shù)債 (RC_dependency_original_issue) 。受到原有的代碼或系統(tǒng)的設(shè)計(jì)問(wèn)題影響,所產(chǎn)生的Bug。
- 代碼/腳本實(shí)現(xiàn)錯(cuò)誤 (RC_wrong_coding) 。單純的代碼寫(xiě)錯(cuò)了,比如對(duì)于函數(shù)的誤用,或者寫(xiě)代碼時(shí)的手誤。
- 環(huán)境,設(shè)施,數(shù)據(jù)庫(kù)配置問(wèn)題 (RC_misconfiguration) 。環(huán)境/基礎(chǔ)設(shè)施/數(shù)據(jù)庫(kù) 的參數(shù)配置錯(cuò)誤引發(fā)的問(wèn)題。
- 前后端接口協(xié)議不一致 (RC_FE&BE_protocol_not_match)
- 前端排版顯示問(wèn)題 (RC_UI_display_issue)
- 兼容性 (RC_compatibility) 。未覆蓋不同操作系統(tǒng)/不同設(shè)備/不同客戶(hù)端/不同窗體大小的差異,引發(fā)的問(wèn)題。
- 非功能性需求 - 性能問(wèn)題 (RC_performance)
- 非功能性需求 - 安全問(wèn)題 (RC_security)
- 非功能性需求 - 健壯性問(wèn)題 (RC_robust) 。連續(xù)點(diǎn)擊,并行,弱網(wǎng)等情況引發(fā)的問(wèn)題。
- 技術(shù)架構(gòu)升級(jí) (RC_tech_upgrade) 。依賴(lài)的包或框架升級(jí)版本引發(fā)的問(wèn)題。
5.Bug產(chǎn)生的人員原因 (Reason)
(1) 維度定義:
描述寫(xiě)出Bug代碼的原因。
(2) 分析目的:
結(jié)合上一個(gè)維度,評(píng)估團(tuán)隊(duì)人員上下文以及技術(shù)的掌握情況。通過(guò)進(jìn)行session/文檔同步上下文的方式進(jìn)行查漏補(bǔ)缺。
當(dāng)分析涉及具體人員的原因時(shí),對(duì)應(yīng)人員可能害怕被追責(zé),會(huì)不自然地產(chǎn)生抵抗心理。所以在我們分析人維度的根因的時(shí)候,側(cè)重點(diǎn)應(yīng)該是團(tuán)隊(duì)對(duì)于上下文的掌握情況,而不是某個(gè)成員的個(gè)體原因,為團(tuán)隊(duì)成員建立有安全感的氛圍,這樣才能保證此維度的分析能持續(xù)進(jìn)行下去。
(3) 維度示例:
- 需求中業(yè)務(wù)需求不夠明確 (Reason_uncovered_detail_in_requirement) 。需求的某些部分可能沒(méi)有清晰地表述出期望的過(guò)程和結(jié)果,在開(kāi)發(fā)的流程中,開(kāi)發(fā)人員對(duì)于該部分內(nèi)容團(tuán)隊(duì)各個(gè)成員也沒(méi)有識(shí)別到該問(wèn)題。導(dǎo)致最終驗(yàn)收時(shí),實(shí)現(xiàn)的內(nèi)容與客戶(hù)/業(yè)務(wù)分析人員預(yù)先期望(或者說(shuō)直覺(jué)性的期望,因?yàn)榭赡軐?xiě)需求的時(shí)候就沒(méi)想到這部分內(nèi)容)的內(nèi)容不同。
- 需求業(yè)務(wù)理解錯(cuò)誤 (Reason_requirement_misunderstanding) 。開(kāi)發(fā)人員對(duì)于需求的業(yè)務(wù)場(chǎng)景理解與實(shí)際業(yè)務(wù)有偏差導(dǎo)致的問(wèn)題。
- 未考慮到邊緣用例 (Reason_unconsidered_case) 。開(kāi)發(fā)時(shí)未考慮到處理某些邊界值或者邊緣場(chǎng)景導(dǎo)致的問(wèn)題。
- 業(yè)務(wù)上下文缺失 (Reason_not_familiar_with_business_context) 。團(tuán)隊(duì)成員對(duì)于需求相關(guān)的系統(tǒng)業(yè)務(wù)上下文的了解不夠全面,導(dǎo)致的問(wèn)題。比如對(duì)于接口的業(yè)務(wù)價(jià)值不了解,從而導(dǎo)致接口返回錯(cuò)誤的結(jié)果。
- 代碼實(shí)現(xiàn)上下文缺失 (Reason_not_familiar_with_code_context) 。團(tuán)隊(duì)成員對(duì)于需求相關(guān)的現(xiàn)有系統(tǒng)代碼結(jié)構(gòu)的了解不夠全面,導(dǎo)致的問(wèn)題。比如更改現(xiàn)有代碼時(shí),漏掉了某個(gè)不熟悉的模塊中的部分相關(guān)代碼。
- 對(duì)于依賴(lài)的接口/工具細(xì)節(jié)不了解 (Reason_not_familiar_with_dependency) 。對(duì)應(yīng)Root cause中的“框架或依賴(lài)功能/接口的錯(cuò)誤使用”。
- 開(kāi)發(fā)過(guò)程中的疏忽 (Reason_negligence) 。單純的開(kāi)發(fā)過(guò)程中的疏忽。
未考慮到系統(tǒng)健壯性或其他非功能性需求 (Reason_unconsidered_non_functional_requirements)
6.自動(dòng)化測(cè)試覆蓋情況 (Original Automation Test)
(1) 維度定義:
描述該Bug相關(guān)的代碼的自動(dòng)化測(cè)試情況,自動(dòng)化測(cè)試代碼為何沒(méi)有發(fā)現(xiàn)該Bug。包括單元/接口/端到端測(cè)試。
(2) 分析目的:
適當(dāng)?shù)淖詣?dòng)化測(cè)試覆蓋與適當(dāng)?shù)倪\(yùn)行頻率可以極大地提高問(wèn)題代碼的反饋效率,所以此維度可以用于識(shí)別系統(tǒng)自動(dòng)化覆蓋的情況。識(shí)別出自動(dòng)化測(cè)試薄弱的功能/微服務(wù)后可以單抽時(shí)間對(duì)其補(bǔ)充必要的自動(dòng)化測(cè)試。
(3) 維度示例:
- 功能沒(méi)寫(xiě)測(cè)試(OT_none) 。因?yàn)閑ffort或其他原因,單純地沒(méi)寫(xiě)測(cè)試。
- 寫(xiě)了測(cè)試但是沒(méi)有覆蓋到邊界情況(OT_not_cover_edge_case) 。寫(xiě)了功能對(duì)應(yīng)的測(cè)試,但是未覆蓋到某些邊界情況。
- 測(cè)試數(shù)據(jù)跟實(shí)際數(shù)據(jù)不符(OT_data_mismatch_reality) 。寫(xiě)了功能對(duì)應(yīng)的測(cè)試,但是所構(gòu)造的數(shù)據(jù)與業(yè)務(wù)的正常數(shù)據(jù)不同,導(dǎo)致沒(méi)有發(fā)現(xiàn)問(wèn)題。
- 重構(gòu)改動(dòng)過(guò)大,原有測(cè)試無(wú)法繼續(xù)使用(OT_remove_by_refactor) 。重構(gòu)改動(dòng)過(guò)大,導(dǎo)致原有功能已有的測(cè)試無(wú)法繼續(xù)使用。同時(shí)重構(gòu)后的新的測(cè)試代碼覆蓋不全。
- 測(cè)試技術(shù)/框架所限無(wú)法覆蓋(OT_none_tech_limited) 。因技術(shù)/框架原因,寫(xiě)自動(dòng)化測(cè)試的effort過(guò)大,或者無(wú)法實(shí)現(xiàn)自動(dòng)化測(cè)試。
- 測(cè)試代碼錯(cuò)誤(OT_wrong_logic) 。單純地測(cè)試代碼錯(cuò)誤導(dǎo)致未識(shí)別到Bug。
7.發(fā)現(xiàn)的問(wèn)題不屬于Bug的場(chǎng)景(Timing_not_bug)
有時(shí)我們最終發(fā)現(xiàn)看到的問(wèn)題不屬于系統(tǒng)的Bug,我們可以把這種情況單獨(dú)分作一類(lèi)進(jìn)行分析其出現(xiàn)的原因(Root Cause維度)。
當(dāng)某種原因出現(xiàn)頻率過(guò)高的時(shí)候,我們也需要采取對(duì)應(yīng)的行動(dòng)去減少此類(lèi)的問(wèn)題的出現(xiàn),以防在大量的調(diào)查處理工作中浪費(fèi)QA及團(tuán)隊(duì)其他成員的時(shí)間。
示例:
- 臟數(shù)據(jù) (RC_dirty_data) 。存在于測(cè)試環(huán)境的臟數(shù)據(jù)導(dǎo)致的問(wèn)題,常見(jiàn)的臟數(shù)據(jù)的來(lái)源可能是未完全開(kāi)發(fā)完成的代碼,團(tuán)隊(duì)成員對(duì)于數(shù)據(jù)庫(kù)數(shù)據(jù)的手動(dòng)更新或插入。一般發(fā)現(xiàn)是臟數(shù)據(jù)導(dǎo)致的問(wèn)題時(shí),需要追查臟數(shù)據(jù)的來(lái)源。如果來(lái)源是現(xiàn)有代碼,則需要單獨(dú)建Bug處理創(chuàng)造臟數(shù)據(jù)的代碼問(wèn)題。
- 新需求 (RC_new_requirement) 。Bug所期望的系統(tǒng)行為并不屬于任何的需求中所約定的開(kāi)發(fā)內(nèi)容,需要新建卡來(lái)進(jìn)行交付。
- 需求問(wèn)題(需求錯(cuò)誤、遺漏) (RC_requirement) 。Bug所提及的內(nèi)容與需求中所約定的開(kāi)發(fā)內(nèi)容一致,但是與實(shí)際業(yè)務(wù)不符,需要新建卡來(lái)進(jìn)行修正。
- 無(wú)法重現(xiàn) (RC_cant_reproduce) 。無(wú)法重現(xiàn)Bug所描述的問(wèn)題,可能是瞬時(shí)的環(huán)境問(wèn)題,或問(wèn)題已經(jīng)被無(wú)意中修復(fù)。
- 基礎(chǔ)設(shè)施問(wèn)題 (RC_unstable_env) 。由于基礎(chǔ)設(shè)施無(wú)法工作導(dǎo)致的問(wèn)題,比如環(huán)境/數(shù)據(jù)庫(kù)無(wú)法訪問(wèn)。
- 外部系統(tǒng)不穩(wěn)定 (RC_unstable_external_system) 。由于外部系統(tǒng)停止工作或者無(wú)法連接導(dǎo)致的問(wèn)題。
- 依賴(lài)的卡未完成開(kāi)發(fā) (RC_dependent_story_unfinished) 。Bug所描述功能的相關(guān)卡還未完全開(kāi)發(fā)完成。需要開(kāi)發(fā)完后再重新進(jìn)行測(cè)試。
- 設(shè)計(jì)如此 (RC_by_design) 。Bug創(chuàng)建者理解有誤或不了解上下文,其實(shí)系統(tǒng)的設(shè)計(jì)與現(xiàn)有行為一致。
最后
雖然列出了這么多維度和原因,但是畢竟每個(gè)項(xiàng)目各有各的情況。所以在bug分析這件事上面,并沒(méi)有適用于所有項(xiàng)目的模板。
但是不管分析的方式及維度如何,我們做Bug分析的目標(biāo)是一致的:
- 分析根因,防止未來(lái)出現(xiàn)類(lèi)似Bug。
- 分析流程和質(zhì)量保障,提前未來(lái)Bug被發(fā)現(xiàn)的時(shí)機(jī),減少修復(fù)成本。
- 分析趨勢(shì),識(shí)別項(xiàng)目質(zhì)量風(fēng)險(xiǎn)。
所以,只要滿(mǎn)足上面的目標(biāo)而且適合項(xiàng)目現(xiàn)狀的分析方式就是好的方式。
以上是我對(duì)于Bug分析維度的一些思考和歸納,歡迎大家指正或提出自己的見(jiàn)解。