談如何提高產品質量
最近,我們的產品上線了,上線之後,穩定是最重要的,但是,出現了幾次bug,都是不應該犯的錯誤,所以,避免bug特別是重大bug出現,提高產品質量,非常迫切。為此,我花了幾天時間,翻一些資料來系統地學習,此文是學習的總結。
產品開發過程產品開發過程:需求分析、設計、編碼、單元測試、整合測試、功能測試、Beta測試和釋出。在工程師開發之前,策劃或產品提過來的需求、策劃的配置檔案或者後期的測試,都可能影響產品質量,但是,本文側重於從開發者角度談提高產品質量。先分享一張來自《Code Complete》的插圖。
可以看到,隨著專案規模變大,架構、設計和整合測試、系統測試需要的時間會更多,而編碼和開發者測試的時間更少。因此,提高效率最為明顯的方法是提高產品質量, 減少測試、除錯和修改所需時間。所以,設計、測試和編碼同樣重要,要分配更多時間,編碼完 != 工作完成。
在很多大一些的IT公司,比如微軟,開發職位叫Software Development Engineer,SDE,軟體開發工程師;測試職位叫Software Development Engineer in Test,SDET,軟體測試開發工程師,可見測試人員本質還是開發工程師。這有別於我們在公司裡常常見到的QA,我是做遊戲的,我見到的QA都是開啟遊戲,然後點點點,從表現上測試功能是否正常,這樣測試是無法全面測試的,這也難怪在很多公司裡QA比開發團隊地位低。我覺得,對於測試這個職位,要做好,是很難的。他要能讀懂策劃文件和開發文件,從源頭上開始著手。如果白盒測試,要能看懂別人寫的程式碼;如果黑盒測試,要和開發人員多溝通,畫出來實現的流程圖,並且分析網路協議;然後,設計完備的測試用例。如果不根據需求、設計和實現,設計完備的測試流程,而只是操作一下試試功能是否正常,很多隱藏的bug是測試不出來的。
在傳統軟體行業:軟體的質量和穩定最重要,代表企業:IBM、微軟、思科等。根據我查到的資料,開發與測試人員比例,微軟1:1,思科1:1.5,普遍在1:1 - 3:1。SDET從需求文件、設計文件開始Review,SDE編碼,SDET寫測試用例,跟極限程式設計的過程類似。極限程式設計的基本過程:構思 -> 編寫測試程式碼 -> 編寫程式碼 -> 測試,編寫測試和編寫程式碼都是增量式的,寫一點測一點,在編寫以後的程式碼中如果發現問題可以較快的追蹤到問題的原因,減小回歸錯誤的糾錯難度。
而網際網路行業:快很重要,有bug在線上也方便修改釋出,更提倡full stack developer,代表企業:
以微軟和google為代表的保證產品質量的做法,都有道理,而且都是成功的。但是,我個人更傾向於full stack developer,第一,招很多SDET對大部分公司都不現實,合格的SDET薪資不會比SDE低;第二,我認為開發人員要對自己的開發的內容負責,主動的想辦法提高產品質量,而不是被動的等測試。
產品質量目標
評估產品質量,常用的是千行程式碼缺陷率,以下是查到的一些業界的千行程式碼缺陷率資料。典型的統計表明,在開發階段,平均50~60個,交付後15~18個;微軟內部測試的產品10-20個,正式釋出產品0.5個;某外包公司,A級≤ 0.5個,B級≤1個,C級≤5個;太空梭的軟體,0個/50萬行。缺陷率做到平均水平的1/10是很少見的,而如果10倍以上,產品可能永遠也不會完工。
跟效能瓶頸一樣,80%的錯誤往往出現在20%的程式碼中。大部分錯誤都是低階錯誤,比如,對需求或設計的誤解、書寫錯誤、賦值語句、邊界錯誤或迴圈錯誤。大多數錯誤是容易改正的。另外,warning是很多錯誤的根源,所以工程裡要禁止warning。
發現錯誤
主要通過檢查和測試。檢查包括:需求檢查、設計檢查、程式碼詳查,測試包括:單元測試、整合測試、系統測試等。有統計資料表明:單元測試的平均錯誤檢出率是25%,整合測試35%,小規模Beta測試35%,系統測試45%。而對設計和程式碼進行詳查的錯誤檢出率分別是55%和60%。
檢查
閱讀程式碼要比測試平均每小時多發現80%多的錯誤,程式碼檢查和測試所獲得的收效之比為8:1。這是因為,錯誤越早發現,解決成本越低。
檢查方法:協同程式設計,詳查需求、設計、程式碼。不僅僅是檢查,要提前思考怎麼做?帶著思考檢查。
單元測試
1. 基於結構的測試。測試用例要覆蓋每一條控制語句,if for while and or switch case等。
2. 資料流測試,避免重複初始化、重複銷燬、定義不使用、未初始化使用等情況,檢測資料流變化。
3. 錯誤猜測:
1). 邊界分析,>=與>的區別,null、size是0的情況,比如測試小於MAX,三種邊界情況<MAX、MAX本身、>MAX,10000個好友/道具的時候會不會導致遊戲卡死?2). 複合邊界,int add(int a, int b),a和b都小於2^31,但是,如果a和b都很大,它們的和會不會出界?
3). 壞資料,太小/大的資料,未初始化的資料,錯誤型別的資料,錯誤長度的資料等。
4). 向前相容和向後相容。比如,遊戲最新版本是2.5,但是有的玩家一直不更新,還是1.0,要相容這些玩家。
整合測試
在單元測試的基礎上,將所有模組按照設計要求組裝成為子系統或系統,進行整合測試。
執行方案
綜合考慮我們團隊的實際情況,最後我制定了“詳查+單元測試+整合測試+系統測試”的方案,來提高我們的產品質量。有些方法,比如協同程式設計、淨室開發,雖然很好,但是對於我們的團隊來說,執行起來太難。ps:我對淨室開發很感興趣,正在研究,研究透以後可能會試著採用。
詳查:先自己詳查,從需求開始,然後是設計和編碼;然後,團隊中的小夥伴互查。關於詳查,有兩點需要注意:1. 檢查前,要先制定程式碼規範,讓開發人員不把精力耗在程式碼規範的爭執上。2. 詳查結果不作為員工表現的考核標準,考核應該基於最終的產品。
單元測試:重點是理清流程,針對每個流程都測試到。整合測試:把單元測試的功能組合起來測試,側重於模組的整體性。系統測試:有點像QA的普遍工作,從功能上測試,各個需求點是否都正常。
執行:我首先制定了程式碼規範,並給大家講解,然後徵求大家的意見統一。然後,寫了一份本文章的內部版本,並給大家詳細講解(為了讓小夥伴們更容易,內部版本細節比較豐富,舉了一些例子,寫的比較囉嗦,稍微精簡、加工之後,形成了這篇blog)。