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