文/ThoughtWorks 楊瑞

我嘗試從幾個角度來分析,在正式分析開始前,我們先把範圍劃定在軟件開發這個圈子裡頭,並且對這些問題進行解釋。關於這方面的討論,一般會存在以下幾個誤區:

  • 將開發階段、測試階段完全剝離。
  • 對測試的理解有些偏差,誤認為測試只是在產品做出來之後,使用它,然後挑毛病,找bug。
  • 誤認為測試只有功能性的校驗。

下頭對這3點逐一解釋:

將開發階段、測試階段完全剝離。

經常有人會問,“為什麼互聯網公司不開除測試,轉而讓大眾來測,找到一個bug給100元?”

這個問題有個假設,就是開發階段、測試階段完全剝離開了。開發階段單純地就是開發人員敲代碼,然後出來的東西交給測試人員去做測試。
我不否認,現在依然存在這樣的實踐方式。但是,這不是一個好的方式。因為這種流程,把發現bug的時間點推遲了。而發現bug的時間點越靠後,修復它所要付出的代價就越大。

這點應該很容易理解,比如你敲釘子,如果一口氣敲完了才發現,敲歪了,那就得拔出來重新來,可是東西上已經有一個很深的洞了。所以,好的方式是敲一敲,檢查一下,隨時糾正方向,確保前進的大方向是正確的。

軟件更是如此,某個bug可能是在最底層的地方發生的,如果早期發現,定位也容易,修復起來被牽扯到的地方也少,付出的代價可以接受。因為bug的產生可能是多個原因,有可能是功能性的,也有可能是對業務理解的偏差導致開始就做錯了。

如果在產品做出來,發布給最終用戶之後才發現。那個時候再排查到底哪裡出了問題,就不是一時半會能做到的了,代價很大。

所以比較好的實踐方式,是由專業的業務人員把要做的東西切割成足夠小的、彼此獨立的、可單獨交付的模塊,開發、測試以及業務人員及時溝通、及時反饋,一個一個小模塊完成,隨時做隨時測。把發現bug的時間點盡量往前推,這樣就可以把修復它的代價降得盡可能小。

當然,小模塊都通過測試,並不意味着所有小模塊拼裝起來組成的系統一定正確,還需要進行層次高一點的集成測試。這就引出了第2點。

測試就是找bug的?

對測試的理解有些偏差,誤認為測試只是在產品做出來之後,使用它,然後挑毛病,找bug。

有這樣的偏差並不奇怪,因為執這樣想法的人太多了,甚至包括一些軟件行業的從業人員。比如有這樣的說法:

開發就是敲代碼的,測試就是找bug的

如果是業外人士,我覺得有這樣的誤解沒什麼。畢竟,隔行如隔山,但業內人士這樣理解的話,真的不知道該說什麼好了。開發是不是只管敲代碼,這裏不談。這裏我們要談的,是,測試不是單純的找bug。

現在我們承接第1點,來說說為什麼測試不是在產品做出來之後,單純的找bug。

先科普的一個東西,就是測試金字塔。


這是Martin Fowler的一篇博客中提到的《TestPyramid》。

看不懂這個圖沒關係,我來慢慢解釋。

測試是分層的,它真的不是只有在產品做出來后才開始的,並且也不能那個時候才開始。原因在第1點里已經解釋過了。一個工程級別的軟件產品,它的測試大致覆蓋了代碼級別的單元測試,模塊級別的API測試,還有端到端的集成測試。這並不全面,還有很多其他類型,這裏我們只是大概分成這3種,便於解釋、理解。

底部那層,就是代碼級別的單元測試。它是發現bug的最前沿陣地,能在這個層級抓住的bug,修復起來的代價,會小很多。而且這部分測試數量很大,驗證的東西也不是最終用戶所能理解的,通常都是自動化運行,有很多種框架可供選擇。只有這層的測試全部通過,才會運行後面更上層的測試。

中間那層,是service級別的測試,大概可以理解成模塊間的API測試。到這一層,基本每個模塊的功能都得到了保障,但是他們彼此的協作不一定正常,所以這層集中要測的就是不同模塊間的協作、通信了。這部分測試數量第二多,也是自動化運行。通過之後,就可以開始最上面那層的測試了。

頂部那層,這部分測試的數量最少,是UI級別的測試。測試的過程大致可以認為是,模擬使用產品的過程,最終用戶也能理解了。比如從註冊用戶開始,到註冊成功,登錄成功,頁面正確加載。這種校驗最基本功能的測試,叫冒煙測試,確保產品可以正確運行,沒有無法啟動之類的重大缺陷。除此之外,還有部分不便自動化的測試,需要手動測試,同時還會校驗一些邊角的情形。

即便上面說的測試全部通過,也不能確保產品萬無一失沒有bug,這是不可能的。只能說,通過了那麼多層的測試,產品處在一個穩定狀態了,最終用戶的使用體驗良好,絕大部分需求都可以滿足。

誤認為測試只有功能性的校驗。

之所以有人會這樣認為,可能是覺得測試只是在使用產品的過程中,發現了功能上、界面上不合理的地方,報告給開發,他們修復,就結束了。

其實不然,測試除了功能性的校驗,還有安全方面的測試、性能方面的測試、兼容性的測試,等等等等。一個負責任的企業,不可能把包含安全漏洞、性能奇差、對運行系統有各種吹毛求疵嚴酷要求的產品發布給普通用戶,就算他們敢發布,用戶也會選擇唾棄他們。所以在發布產品之前,肯定有這方面的測試,而這方面的測試,不是普通用戶所能勝任的。

喏,現在看到了吧。其實測試也是一個複雜的工程,並非單純的使用最終產品,找到其中的缺陷和問題,再提交這麼簡單的事情。

說到這裏,我猜想,所謂的“讓大眾去測試,去找bug”,很大程度應該是指測試金字塔中,位於頂層的那部分。讓用戶通過自己的使用,遇到bug直接報。

也有人說,單元測試那些是開發做的。對於那些測試金字塔中層級較低的測試,可以由開發人員或者其他相應的技術人員在產品發布前解決。對於那些層級高的,比如UI級別的測試,可以分發出去,讓最終用戶來測試,並且獎錢!

OK,沒問題。那就依照這個說法,我再來解釋為什麼UI級別的測試也不能不管不顧的直接扔給最終用戶。前面有人也提到了相關的東西,我在這裏依舊分幾點來說,先來個summary,主要是這幾個點:

  • 測試是一項工程,需要計劃、策略。不能無腦亂來。

  • 對於bug的描述和修復,是有相應要求的。普通用戶做不來。

詳細解釋如下:

1、測試是一項工程,需要計劃、策略。不能無腦亂來

即便對於大家認為沒有技術含量的手動測試,也要制定相應的測試策略、測試計劃。確定使用什麼方法去測試產品,如何測試,開展測試時如何組織測試用例,人員如何分配,團隊如何分工合作。如果沒有這些綱領性、指導性的東西,面對產品那麼多的功能,全憑腦子想,用到哪裡測到哪裡?這個真有點天方夜譚了。蘇傑的回答中已經提到不少。

要構建這麼多測試,是需要團隊內的人員一起努力、合作的。要考慮哪些東西需要提前注意,哪些情況需要單獨拿出來測試,哪些東西不重要可以不測。在開發的過程中就盡量避免出現問題,而不是等它出現再修。

2、對於bug的描述和修復,是有相應要求的

還是那句話,測試是一項工程。發現了bug,需要把它用合理的形式記錄下來,反饋給開發方,再經過多方人員的溝通,修復,回歸測試,才能確認修復好了,再次發布產品。

對於記錄bug也有一些要求,比如要闡明在運行什麼系統下、系統的版本、產品的版本、如果是瀏覽器中打開還要標明瀏覽器版本、重現步驟、提供截圖、提供測試賬號。

開發人員拿到bug后,可以根據那些信息嘗試快速地復現bug,再定位,再修復。如果中間出現問題,需要跟報bug的人員溝通、確認,是產品本身就如此設計的?是偶然發生無法復現的?是優先級很低暫且不用管的?

這些事情,如果是在團隊內,很好實施。如果需要跟用戶做這樣的溝通,那真是……費死牛勁了。所以,即便大家都認為沒有技術含量的UI測試,也不能直接扔給用戶去做。

最後,最重要的一點在這裏:

  • 用戶使用產品,享受的是體驗。
  • 目的是高效舒服地解決自己的問題。

如果沒有任何測試,直接把產品扔出去,讓用戶負責測試。前面提到的安全、性能、兼容性還有功能上的各種問題,任何一個都會導致用戶崩潰。

所以,無論如何都不能把質量沒有保障的產品,直接扔給最終用戶去做測試。

最後感慨一下,大家普遍對測試有一定程度的誤解,覺得測試就是在界面點點點,找幾個茬,就算完事了。

其實,測試需要專業的人士,需要對產品的透徹理解,需要對用戶的同理心,需要對市場的把握,需要足夠好的大局觀,需要足夠的耐心,需要一定的技術功底,需要寬泛的知識面,需要良好的溝通能力,需要能夠協調團隊中不同角色。

說的好像很高級,好多事情是產品經理或者項目經理乾的活,但是,說實話,想做一個好的測試人員,這些東西真的都需要。當然,如果願意踏踏實實做一個點界面的人,那就不需要這些。

再響應一下現在很熱的口號,“工匠精神”,作為一個有工匠精神和責任心的企業,怎麼能容許自己的產品質量沒有保障就直接交付給用戶呢?

Google出過一本書,叫《Google軟件測試之道》,裏面提到過一些觀點,原話記不清了。我說說我的理解:

  • 盡量把測試往前推,儘早發現,降低修復成本;
  • 測試的目的不是發現bug,而是預防bug的發生;

當各種測試做的足夠好的時候,即發布的產品質量有足夠保障時,一些不重要、影響小的問題可以不考慮,直接發布產品,用戶發現提出反饋后,酌情修復;

通過各種技術手段和流程改進,逐步的解放公司內部測試人員,讓他們把精力放在對產品的把握上。


分享