開發要不要自己做測試?怎麼做?

現在包括 GoogleFacebookeBay 等一線互聯網巨頭公司都在逐漸推行“沒有專職測試,測試工作由開發人員完成”的全新模式,原本專職的業務功能測試團隊的規模逐漸縮小,有些甚至已經完全沒有了,而原本的測試開發團隊逐漸在向工程效能(Engineering Productivity)團隊轉型。這些互聯網巨頭之所以能夠很好地落地這種全新的模式,是因爲他們都較好地解決了這個模式的兩個最大的難題:

  1. 開發人員如何能夠勝任測試

  2. 工程效能團隊如何賦能開發人員,幫助開發人員高效地完成高質量測試

本文會圍繞這兩個問題來展開討論。首先讓我們一起看一下開發人員自己做測試都會遇到哪些問題和阻礙。

開發人員自己做測試會遇到哪些問題

人性角度引發的問題

首先從人性的角度來看,開發人員通常是屬於“創造性思維”,自己開發的代碼就像是親兒子一樣,怎麼看都覺得實現很棒;而測試人員則屬於“破壞性思維”,測試人員的職責就是要儘可能多的找到潛在的缺陷,而且專職的測試人員通常已經在以往的測試實踐中積累了大量典型的容易出錯的模式,所以測試人員比起開發人員,往往更能客觀且全面做好充分的測試。

思維慣性的問題

剛纔是從人性角度上來講的,如果從技術層面來看,由開發人員自己測試,會存在嚴重的“思維慣性”,通常開發人員在設計和開發過程中沒有考慮到的分支和處理邏輯,在自己做測試的時候同樣不會考慮到。比如對於一個函數,其中有一個 String 類型的輸入參數,如果開發人員在做功能實現的時候壓根沒有考慮到 String 存在 Null 值得可能性,那麼代碼的實現裏面也不會對 Null 值做處理,連帶結果就是測試的時候就更不會設計 Null 值得測試數據,這樣的“一條龍”缺失就會給代碼的質量留下了缺陷隱患。更糟糕的是,對於這種情況,即便啓用了代碼覆蓋率指標去衡量測試完整程度,也不能有效暴露這類問題,因爲處理 Null 值得代碼壓根沒有寫,又何來代碼覆蓋率一說吶。

被測試環境和測試執行環境的複雜性問題

有專職測試的時候,測試工作是專職測試人員完成的,專職測試人員通常會負責搭建被測試環境以及管理測試執行環境。被測試環境好理解,就是 System Under Test(SUT)。而測試執行環境是指用於執行測試用例的機器,比如對於 Web 的 GUI 測試,最簡單的測試執行環境就是你本地機器上的瀏覽器。但是對於大型互聯網企業,測試執行環境遠遠要比你想象的更復雜。通常都是一些大型的測試執行集羣,甚至是內部的測試執行私有云,比如用 Selenium Grid 搭建的 GUI 測試執行環境,往往這樣的集羣都會有成百上千臺機器,再比如用 Appium+Selenium Grid 搭建的移動設備測試集羣,也往往會有上千臺設備。現在沒有了專職的測試人員,那就需要開發人員自己去管理、維護和搭建這些測試基礎架構,這樣做其實是得不償失的,工作量本身並沒有減少,只是換了一批人來做同樣的事情,而且開發的精力往往更應該花在構建新的業務功能上,而不是用在維護測試基礎設施。

測試數據準備的問題

測試數據準備是測試過程中必不可少的關鍵步驟,有專職測試的時候,是由測試人員來準備測試數據的,一方面測試人員往往比開發人員在全局層面上更瞭解被測系統,所以對於測試數據的設計與生成也會更高效,另一方面測試人員在以往的測試過程中已經積累了很多測試數據生成的方法和小工具。現在這些都需要開發人員自己來完成了,無疑進一步加大了開發人員的工作量,而且開發人員往往對跨模塊,跨系統的測試數據準備缺乏系統性的理解,往往爲了生成一條非自己業務領域的數據而花費大量的學習成本。舉個例子,假設現在“買家模塊”的開發人員需要測試“商品買入”的操作,那麼就需要事先準備好“可以被賣的商品”,這就意味着“買家模塊”的開發人員需要明確知道“賣家模塊”和“商品模塊”的細節,才能生成“可以被賣的商品”。這類問題在目前主流的微服務架構面前會更嚴重,原因是爲了產生一條測試數據,可能會需要依次調用很多個服務。

測試執行與 CI/CD 集成問題

對於不同的業務開發團隊,各個階段採用的自動化測試框架可能都不同,比如有些會使用基於 Java 的 Selenium,也有些會使用基於 JavaScript 的 Nightwatch 等,有專職測試的時候,各種不同的測試框架與 CI/CD 的集成,都是由各個業務團隊的測試人員和 CI/CD 的人員一起完成的,現在沒有了專職測試,這部分工作就需要開發人員自己和 CI/CD 人員一起完成,這就要求開發人員不僅需要非常熟悉自動化測試框架的細節(很多時候爲了更好地和 CI/CD 集成,會對開源測試框架或者是自研測試框架做二次開發,比如改進 retry 機制,增加覆蓋率統計等等),還必須瞭解 CI/CD 的流水線設計以及腳本設計,然後再將需要支持的自動化測試框架的運行命令行和需要暴露的參數(測試用例 Git 路徑、測試執行環境、測試報告路徑等等)寫進 CI/CD 的腳本。這些工作在很大程度上分散了開發的精力,對於提高開發自身效率是非常不利的。

失敗測試用例歸屬問題

有專職測試的時候,開發人員往往只關注自己修改部分相關的測試用例,模塊或者服務的全迴歸測試中如果有失敗的測試用例,通常是由測試人員跟進去分析具體原因,並協調解決然後才能發佈上線。但是現在開發人員負責所有測試,他就必須關注全局的測試。舉個實際的例子來看,比如“用戶登錄”服務的開發工程師修復了一個缺陷,然後本地自測通過後遞交了代碼,然後很不幸,在 CI/CD 的流水線上全迴歸測試卻發現有部分用例失敗了,雖然這些失敗的用例和這次的代碼修改沒有任何關係,但是爲了保證自己的修改能夠順利上線(CI/CD 的流水線要求只有全迴歸測試 100% 通過纔可以上線),他必須挨個去分析失敗的測試用例然後自己去找到對應的人去協調解決,這顯然是非常不合理和不敏捷的做法。

歸根結底,這些問題的本質都會直接影響開發人員本質工作的進度和效率,那麼我們應該如何解決或者在一定程度上緩解這些問題呢?這就是接下來要討論的問題,工程效能團隊如何賦能開發人員,幫助開發人員高效地完成高質量的測試。

工程效能團隊賦能開發人員進行高效率高質量的測試

賦能的基本思路是能夠讓開發人員更專注於測試本身,而從那些輔助測試的工作(比如搭建測試執行環境、CI/CD 集成等)上解放出來,這些輔助測試的工作由“工程效能”服務或者相關支持工具鏈來統一解決。這個思想和和目前非常流行的 Service Mesh 的設計思想不謀而合,Service Mesh 也是可以讓服務的開發人員可以把所有的精力集中在業務功能的實現上,而不需要去關心服務間通信的基礎設施,像類似於服務的註冊與發現,熔斷機制等都會統一由 Service Mesh 以對業務應用透明的方式來實現。這些“工程效能”服務或者相關支持工具鏈通常都會由原本從測試開發轉型過來的工程效能團隊來設計和開發。那麼我們接下來看一下可以提供哪些“工程效能”服務或者相關支持工具鏈,並且能以什麼樣的方式來解決或緩解上面提到的開發自己測試帶來的問題。

測試執行服務(Test Execution Service)

CI/CD 各個階段所有的測試執行發起都通過測試執行服務(TES,Test Execution Service),TES 通過統一的 Web Service 接口與 CI/CD 以解耦的方式進行集成。無論是 CI/CD 流水線,還是開發人員執行測試,都通過 TES 來發起,唯一的區別是開發人員一般使用 TES 的 UI 界面發起測試,而 CI/CD 是直接在流水線腳本里面調用 TES 的 Restful API 發起測試。測試執行服務的輸入參數也很簡單直觀,通常只包括測試框架名字、測試用例集版本號、測試用例路徑、 測試報告獲取方式、同步 / 異步執行開關等。一旦調用 TES 發起測試,後續如何調用 Jenkins job、如何打包下載 test jar、如何找到適合的測試執行環境、如何發起測試以及如何收集測試報告等都對使用者完全透明。可以想象,現在,開發人員在和 CI/CD 集成以及執行測試的時候,已經可以完全不需要去關心執行測試的命令行、發起測試的 Jenkins job 以及配置、測試的具體執行環境、測試報告獲取等信息。這將大大提高開發人員自己執行測試的效率和便利程度。

測試數據服務(Test Data Service)

前面提到過,跨模塊,跨系統的測試數據準備對於開發自己做測試是個挑戰,尤其是現在大量採用微服務架構,這個問題就會更突出。測試數據服務(TDS,Test Data Service)將會以 Web Service 接口的形式爲所有類型的測試提供一致的測試數據準備入口。無論開發是要做 API 測試,還是 GUI 測試,或者是性能測試,都可以通過調用 TDS 的 Web Service 或者 UI 來準備各種組合類型和量級的測試數據。TDS 本身還是個開發平臺,任何開發人員都可以通過腳手架代碼來貢獻新的數據類型支持,並且 TDS 平臺本身藉助自己的 Core Service 和內建數據庫具有元數據管理能力,能夠提供諸如測試數據數量以及質量的管理。下圖展示了典型的 TDS 架構設計簡圖供參考。

測試執行環境服務(Test Bed Service)

正如前面提到的,測試執行環境對於大型企業來說是很龐大複雜的,爲了方便開發人員使用測試執行環境,或者說爲了使測試執行環境對於開發人員透明,就需要引入測試執行環境服務(TBS,Test Bed Service)。TBS 的主要職責是負責管理、創建,擴容 / 收縮測試執行集羣。一個常見的測試執行環境架構如下圖所示,TBS 會根據等待執行的測試用例的排隊情況,動態決策測試執行集羣的節點數量和類型,通常會使用 Docker 和 Kubernetes 來實現 TBS 的 Gird 管理。

構建工程效率工具鏈倉庫(Engineering Productivity Tools Store)

類似於 App Store 的概念,可以把各種測試小工具以及提高效率的工具集統一在 Engineering Productivity Tools Store 裏面集中版本化管理。比如文章開頭我們提到過開發自己做測試的時候存在思維盲區,對於像 String 這樣的參數可能遺漏 Null 值得用例,我們就可以開發一個小工具對被測函數的輸入參數類型基於邊界值自動生成邊界測試用例,比如 String 類型的參數一定會生成 Null,SQL 注入攻擊字符串,非英文字符,超長的字符串等,這樣就可以系統性地避免開發的盲區。諸如此類的工具還有很多,以後有機會再和大家一一分享。

測試即服務(TaaS,Test as a Service)的全局架構

除了以上的內容,其實還有諸如測試報告服務(TRS,Test Report Service)、全局測試配置服務(GRS,Global Registry Service)和用於 API 測試解耦的 Mock 服務(Unified Mock Service),由於篇幅無法一一展開。需要強調是的是,這裏談到的很多服務已經在某些企業內部有了落地實踐,並取得了很好地效果。最後,以 Test as a Service 的全局架構圖來結束本文。

作者介紹

茹炳晟,eBay 中國研發中心測試基礎架構技術主管,極客時間《軟件測試 52 講》專欄作者。先後任職於 HP 軟件中國研發中心、阿爾卡特朗訊、Cisco 中國研發中心等公司。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章