1. 程式人生 > >關於軟體測試的理解和反思

關於軟體測試的理解和反思

上一篇裡我們討論了測試的必需性,如果大家目前還在公司裡做著測試的工作,那就說明還是落在必需的範圍裡面,或者至少一段時間是吧。那接下來我們看下既然需要做測試,需要做哪些事情。
基於我自己的一些理解和觀察,我試圖把測試工作的層次分成三個階段,越到後面涵蓋的範圍越廣。這裡討論的一些做法可能更偏向於網際網路方面的測試,特別是第三個階段。

首先我想先從一個例子開始,一個現實生活中的例子。
對於一個城市,假設我們的工作目標是提升環境的質量,減少垃圾。那麼我們可以做什麼?
首先,我們可以請很多環衛工人,出去打掃各個街道,這個馬上就有了效果,環境變得更乾淨了。但是還不夠好的地方是明天還是有很多東西需要打掃,治標不治本,只要一停下來立馬回到之前的狀況。

接下來,我們往前面想一想,為什麼有那麼多垃圾呢?其中一個方面是很多人亂扔垃圾。所以更進步一點的方案是,對於亂扔垃圾的人有些約束或者懲罰,比如抓到了曝光或者罰錢,這樣扔垃圾的人會變少。
再然後,我們發現即使做到了上面,還是有不少垃圾,而且上面強制的方案也帶來不少的反感。我們需要更深層次的思考,為什麼會有那麼多垃圾?是因為垃圾桶太少?設計得不合理?如果是這樣,就需要從其他公共設施方面做一些改進了。

對於我們的測試工作,也是有類似的思路,只不過細節上要考慮更多。

第一個階段:發現和解決bug的階段
這個階段的思路基本上儘可能發現更多的bug,見一個滅一個,來兩個滅一雙。
  發現bug,解決後驗證bug,沒有任何根源性的推動,或者推動的效果不好。


這個階段,測試工作主要集中在發現bug,要做好這個,需要多個方面的努力,比如下面這些:
- 更高效的發現bug,考驗測試設計的能力。
   這方面有非常多的方法和技巧,以及經驗,這裡不細說。
- 發現bug之後如何清晰的描述,定級,以及跟進和驗證。 
   這個看似簡單,但是你會發現很多測試工作做了幾年的人這樣的基本功還是不夠紮實。也可能沒有受到過很好的訓練或者一直沒有人指導。
- 對業務和架構的理解能力。 
   沒有這方面的能力,很難發現一些深層次的bug。而這樣的能力對於快速學習和一些技術基礎也有不低的要求。
- 發現bug之後如果舉一反三的儘早發現更多類似的bug。

大家看到的很多經典的測試書籍講的基本都是這個階段做的事情,比如Software Testing,How We Test Software at Microsoft,以及探索性測試相關的書籍,都是專注在如何更高效的發現缺陷。


上面這些東西都是一個業務測試人員的基本功。看似簡單,但是做好並不是一件容易的事情。也許這些事情一點都不cool,不sexy,甚至去做職級評審的時候不佔優勢,但是對於系統質量的提升,是切切實實帶來很大幫助的,其工作的價值應該得到認可。但是如果一直停留在這個階段,就陷入到上面例子中說的掃馬路的階段,因為如果沒有其他方面的改變,每次都有那麼多的bug。

不過很多時候,我們的測試停留在這個階段也是因為現狀,考慮下這樣的情況:
- 開發基本不自測,甚至沒有自測的環境,特別是涉及多個系統的對接。
- 提測後很多基本的功能都不能正常使用
- 專案管理比較混亂,但是最終的釋出日期又被老大們定死,所以測試時間常常被壓縮
而且,而且沒有對於開發人員的質量方面的考核,那麼很長一段時間,我們的測試將處於這個初級階段。

我相信目前還有不少的團隊是處於這樣疲於應對的情況下,不只是小公司,可能一些大公司的部分專案也是如此。隨著整個研發體系的發展和深入,我們應該有更高的追求。
第二個階段:質量的管理
在第一個階段中,可能有一些人會停下來想:我們一直這樣下去也不是個辦法?有沒有更好的做法呢?

最直接會想到的就是,怎麼讓別人少丟垃圾,讓本身的bug就更少一些。如果我們做的工作只是發現bug解決bug,那麼就是一個消耗戰。不能形成一個良性的迴圈,就不能持續的優化,工作的長期累積價值就體現不出來。
這個階段核心的思路是對缺陷做分析和考核,並做研發流程中主要問題的梳理和改善。

常常做的事情可以從下面幾個方面來看:
1. 做質量資料的統計和分析
    收集的資料很多,常見的有:
     - 外網的bug情況,包括事故,及影響的程度
     - 測試階段的bug數量,分佈(按系統,團隊,開發個人),嚴重程度,bug的類別等維度
     - bug的橫向跨團隊和系統的對比,縱向的和歷史情況對比
     - 版本釋出的情況,程式碼變更行數的情況
   從這些資料的收集中就能發現很多問題,比如問題集中在哪裡,哪些模組,哪些人,哪些類別等等,以及有沒有改善。

2. 問題的追溯和對於開發的考核
   這個方面也許有一些爭議,但是我還是覺得這個是一個很重要的方法。光靠觀念和自覺是不夠的,必需要有一定的反饋機制,就好比交規一定是配合著扣分和罰款等手段,否則記錄闖紅燈有什麼意義呢?而且現實的來說,這些方法起到約束的作用,也是一種心理暗示,要做自己做的東西負責,也便於養成好的習慣。
    通常的考核指標涉及這些方面:
    -  編譯失敗次數的考核
    - 外網事故和bug的數量
    - 測試階段的bug,特別是基礎功能bug和嚴重bug
  粗略的列了這麼多,其實可以有很多,比如配置檔案改錯的情況,漏提測檔案的次數等等。

這裡也許有很多的討論,但是讓我們看看一個實際的例子。下圖是某個系統的編譯失敗的情況,在11月份的時候提出要統計並公開(並無懲罰條款)編譯失敗的情況,包含到開發的團隊和個人等明顯,12月份開始出現了明顯的下降並穩定了。這個圖隱藏了一些細節,如果剔除其他因素只看開發程式碼原因的編譯失敗則更明顯,特別是後面有懲罰機制之後,進一步下降。
     

編譯失敗大幅的下降一方面是節省了大家的時間,另一方面其實也是提高了版本質量,想想如果有很多的編譯失敗,而且是到提交測試的階段,這樣的程式碼質量能好嗎?是可能做過自測嗎? 有了這樣的機制,至少會更仔細一些。

對於bug方面其實也是一樣,如果開發在乎(或者被迫在乎)外網bug或者被測試發現的bug數量,他寫程式碼的時候一定會更仔細,也會做些簡單的自測,讓提測的質量更高,提高了整個研發系統的效率,同時也是提升了質量,因為quality must be built in。

我個人的經驗,作為測試人員幾乎同時面對過兩個開發團隊,一個有上述的考核,一個沒有。表現出來的版本質量和對質量的關注完全不一樣,而且前者也並沒有出現開發和測試的對立,以及測試不敢提bug等負面的情況。

3. 對於測試的考核
除了對於開發的考核,同樣也有對於測試的考核,這樣也更加的公平。
測試的考核通常考慮下面的指標:
     - 漏測:絕對數量或者漏測率
     - 版本的工作量和測試效率
     - 釋出延期的情況
如果測試有這樣的壓力,也需要不斷努力去發現更多的bug。

說起考核,總有人覺得這不符合智力勞動的情況,或者網際網路的作風,其實不太理解為什麼會這麼覺得,放眼望去,有什麼工作不被考核呢,sales要背quota,為什麼軟體開發和測試不能對自己的工作的質量負責呢?當然,具體的指標如何去定才更合理那是另一個要去考慮的。
換個角度來看,適當的壓力(不應該導致焦慮和扭曲的做法),其實是讓一個人表現最好的狀態。

4. 推動開發的自測
這個問題一向是個老大難問題。願意自測的開發團隊你不用太多的推動,不願意做的推動也很難,或者你無法判斷他有沒有做自測。而且這方面,通常取決於開發負責人的觀念和態度。
如果是介於之間的,我們可以做一些事情,比如:
    - 統計測試階段的bug中,屬於開發可自測發現的比例。通過這個可以看有多少bug是不應該到測試階段的,以及橫行縱向的對比。當然這個標準要自己拿捏。
    - 給出一個自測的checklist。開發在提交前要完成這個list並正式的給出報告。這個方式我們曾經在一個專案中用過,效果不錯,基本功能都通過這個保證了,前提是開發負責人認可。
    - 有一套自動化驗收的用例,可以掛接到自動部署之後或者daily build。前提是我們的自動化要足夠的問題,效果才會好。

這個階段除了業務測試的努力,也體現出了QA的價值。這裡的QA是指質量管理,有的地方叫SQA,專注在質量度量和研發流程的管理上。

到這個階段,發現事情順了很多,質量也有更大程度的提升,並有改善額趨勢。
第三個階段:推動全面的質量提升
到上面第二個階段,我們發現質量有了一定的提升,但是還是有不少的問題,而且有些問題需要我們把思路和眼界拓寬來看。這裡討論的一些東西可能更適合網際網路的產品。
這裡列一些我們可以去做的事情,受限於個人的經驗,可能還很片面。

1. 研發流程的梳理
其實在階段2的時候也可能有些團隊已經開始做這樣的事情,因為在分析質量和效率問題的時候,我們發現很多問題不單純是程式碼的問題,可能還涉及研發流程的很多方面,比如:
  - 需求不清楚
  - 跨團隊的配合問題
  - 程式碼版本管理
  - 技術方面的評審和大家的理解
所以整個研發流程的規範和梳理,以及配合對應的需求和版本管理的系統也是非常的必要,實際中發現效果也是比較的明顯。而且還有一點體會,在接手一個很混亂的狀況時,這樣角度的數量和調整比技術方案的引入更重要和切中要點,能從40分到60分,技術是往80分走的過程效果更明顯。


2. 提交測試前後做的一些事情
  - 程式碼的靜態掃描
     這個方法很多的團隊都在做,但是實際的效果似乎差別很多,而且ROI也很難說,不過從方法本身來說還是值得去做的,對測試人員也提出來更高的要求。
  - code review
     這個開發應該要做,特別是開發間的交叉review,非常的有幫助。不過這個也和自測一樣,取決於開發負責人的態度。另外,測試也應該去做,特別是對於diff 程式碼的review,我們檢查做了大概兩個月的時間,發現還是非常的有收穫。發現了一些黑盒難以發現的問題,以及開發的程式碼夾帶,並且對於這個版本影響範圍的評估也更準確。但問題是短期會花費測試更多時間,以及需要測試人員有一定的技術能力。
   



3. 測試能力的提升
    測試階段有很多的事情可以去做,覺得最主要的還是兩個方面
     - 自動化。 越來越覺得這個是繞不開的話題,要想盡辦法去做,做得更高效更全面。前面有篇blog也提到了一些輕量級的做法,業務測試的團隊可以參考 http://blog.csdn.net/superqa/article/details/20644285
     - 輔助手段,比如程式碼覆蓋率,特別是差異的覆蓋率。這個大家都比較容易理解就不展開了。
     - 拓展測試的型別
     這個方面說起來有些泛,需要結合團隊和業務的情況,比如安全測試,效能測試,相容性測試等,去發現一些對於產品來說很重要的風險。
     這方面有兩個前提,一是我們的基本功能質量到了一個階段,可以讓大家騰出手去拓展測試的面,另一方面我們測試人員的能力要跟得上。

4. 釋出環節的質量把控
     這個方面和傳統的測試不太一樣,而且瞭解到不同的組織做法不同,執行釋出的人員可能不同,有開發,運維,專職的版本管理或者測試來做。
     在我們的實踐中,釋出後來都逐步收到測試這邊,回頭來看覺得還是有不少有幫助的地方。當然也不絕對的必須測試來做。
      - DO分離,避免了隨意的釋出,特別是在開發手上的時候。所有的bugfix都經過測試釋出,可以更準確的度量質量(除非這個問題可以不修復,否則肯定要過釋出環節)
      - 知道最近發了什麼,可能的影響是什麼,需要線上關注什麼。
      - 灰度。 網際網路產品常用的一個控制風險和節奏的手段。
      - 擴容的快速自動化檢查,這方面也依賴於自動化的建設。
      - 釋出過程支援灰度的控制,備份和快速的回滾。對釋出系統有一定的要求,而且有可追溯性。

    


     釋出處在整個研發流程非常關鍵的節點,在這個點可以做很多的控制,也能發現很多的問題,對於測試團隊來說,從這裡可以發現很多的問題,做很多的提升,對自己和相關的合作團隊。

5. 外網的監控
    發現釋出後的問題,持續運營過程中的問題,推動優化。
    通常監控可以分幾個層面,粗淺的可以分成幾類:
    - 運維層面的監控,比如機器,鏈路,資源使用,主要元件是否正常等。
    - 業務指標的監控,比如來自點選率,BI系統等。
    - 整合在產品裡面的監控程式碼,我們稱之為模組呼叫監控。這個是全量的,有次數,成功率,響應時間等角度。  
    - 測試層面的自動化監控,關於在介面和功能層面。這個是取樣的,但是從使用者的角度來監控。
      

  以上這些監控都有對應的告警機制,可以第一時間發現問題,避免造成更大的損失。為了實現上面的監控需要做大量的工作,但是這些對於整個外網運營的質量非常的重要。

6. 外網事故和問題的收集,跟進和反向推動
     和前面的思路一樣,如果只是發現問題解決問題還是稍顯被動,那麼對於外網事故和問題的分析,還是有很多推動性的幫助。

7. 使用者的問題反饋和滿意度
     進一步的質量不只是系統本身的質量,而是從使用者角度看到的質量,有時候這個可能稍微超出一些系統層面的問題,但是因為最終的質量還是使用者說了算,所以我們應該擴充套件下思路。收集這樣的問題的渠道有很多
     - 外網問題反饋,比如來自客服系統的,使用者直接的反饋,現在很多app上都有反饋的功能。
     - 論壇資訊的統計收集。我瞭解的另一個測試團隊,他們還專門開發了一個自動收集外部反饋,以及過濾分析的系統來幫助他們及時的瞭解外包的問題反饋。
    

8. 運營層面的質量
  更進一步,關注運營方面的質量,跳出傳統意義的質量的範疇,關注我們的業務指標,不只是做一個高質量的產品,而是做一個業務上成功的產品。
   比如下面這樣的例子:
     - 商品詳情頁的圖片的質量
     - 活動頁面和詳情頁面價格不一致的情況
     - 運營配置的錯誤導致的問題,哪些是可以監控發現,哪些是可以推動運營平臺的規則檢查?

      

每次我們的思路跳出一些框框,都會有不同的領域。有點點哲學上的意味,很多領域做到後面,其實會超出那個領域本身的範疇。就好比高效能的汽車,到後面就不得不研究空氣動力學這個原本是和航空有關的東西。但是,這是否超出了本意,如果去看待,又是另一個問題。


其實這樣的三個階段也是一個粗略的劃分,並不一定要逐步的來發展,其實都是一些具體的做法和實踐。以我目前經歷過的實踐只想到這樣的層次,應該還有更高階的階段。
我們越到後面我們發現進一步的努力帶來的提升幅度其實不大。但是很多事情也是一樣,從85分到90分付出的努力可能比50到80分的努力還要大。另一個更有趣的是汽車的極速和馬力的關係,家用車100馬力開到180km/h是能做到的,但是超過時速300,每提升一點需要增加的馬力要大得多,到400以上,車時速每再增加一公里,功率需要提升八馬力。這篇文章讀起來非常有意思,http://blog.sina.com.cn/s/blog_4d0109a301000ajz.html



寫到這裡,我們可以跳到整個公司或者業務的層面,來思考一些對於測試更深層次的問題:
測試團隊存在的價值和意義是什麼?
只有對業務有明確的價值,業務測試,或者說整個測試團隊才有存在的意義。只要業務OK,砍掉測試團隊也不是不可能。我們必須時不時的跳出我們自己的思維的圈子,站在整個事業部老大的角度來思考下測試的價值和意義。
在下一篇關於測試組織方面我們可以再討論下這方面的內容。

還有一個體會:測試的水平反應整個研發體系的能力和水平。
如果我們的測試還專注在第一階段,那說明整個研發還比較初級,開發和測試都是溫飽的階段。當我們的測試人員不再趴在地上盯著最基本的功能質量的時候,才有可能擡起來看看更多有價值,有幫助和有長遠意義的工作,慢慢形成一個良性的迴圈。