業務團隊如何高效實施自動化測試

GitChat技術雜談發表於2017-11-22

640.gif?wxfrom=5&wx_lazy=1

本文來自作者 樑士興 在 GitChat 上分享「業務團隊如何高效實施自動化測試」,閱讀原文」檢視交流實錄

文末高能

編輯 | 嘉仔

摘要

美團酒旅的終端研發團隊,在2017年實施了大規模的自動化測試。酒旅的終端研發團隊負責美團在住宿、境內度假、大交通方向的業務研發工作,是一支面向業務的平臺型團隊。

由於其業務屬性,客戶端一直面臨著業務需求壓力大、業務需求迭代演進迅速的挑戰。這樣團隊是否適合實施自動化測試?是否需要付出高額的成本?是否能夠獲得足夠的收益?

下面由我來分享酒旅這次自動化實踐的主要歷程,相信一定能夠給各位朋友帶來幫助。

作者簡介

樑士興,2009年畢業於北京航空航天大學。畢業後在IBM中國研發中心工作了5年。2014年7月份加入到美團大眾點評,現職位為技術研究員。

作為美團酒旅基礎服務平臺負責人,經歷了美團客戶端業務架構演變的全部過程,因而對客戶端的業務架構有了進一步的理解和思考,願意與大家進行分享。

業務團隊是否應該實施自動化測試

按照固有的思維模式,業務團隊通常面臨業務壓力大、需求迭代頻繁等諸多痛點。業務壓力大,意味開發自動化測試程式的人力成本是個巨大的挑戰;

而需求迭代頻繁,則意味著自動化測試的穩定性很難得到保障。這是否意味著業務團隊無法,或者很難實施自動化測試呢?

美團點評的酒旅終端團隊,是典型的業務型團隊。負責美團酒旅在住宿、境內度假、大交通方面的業務建設。

酒旅的終端團隊在2017年實施了大規模的自動化測試建設,因而在這一領域積累了不少經驗和教訓。

我希望從團隊實際遇到的困難與挑戰入手,結合自動化測試的意義,幫助大家決策是否要實施自動化測試。

業務團隊面臨的困難和挑戰

酒旅終端團隊的痛點:

歷史需求時間跨度長,質量保障困難時間跨度最長的超過三年,一些細節包括產品、開發、QA都不能很好的解釋清楚

儘管開發團隊和QA同學都盡力去提升產品研發質量,但是仍然故障不斷。

蘋果封殺熱補技術:

由於蘋果與年初禁用了類似JSPatch的熱補技術,“出現問題線上修復”的質量保證手段也不復存在。

業務對開發效率提出更高的要求

產品經理對研發團隊的訴求概括起來通常只有兩點:

  • 能不能多做幾個需求?

  • 能不能早一點上線,最好明天就上?

如果認真的對待這兩個問題,本質上是業務團隊在研發效率和迭代頻率方面,對研發團隊提出了更高的要求。

綜上所述,酒旅終端研發團隊實際上面臨的挑戰就是:

  • 需要更好的質量保障手段包括保障的效果(少出bug)和時機(上線前暴露bug);

  • 需要更高的研發效率和產品迭代頻率。一個字,快!

自動化測試的意義

軟體測試的定義是:在規定的條件下對程式進行操作,以發現程式錯誤,衡量軟體質量,並對其是否能滿足設計要求進行評估的過程^1

自動化測試是使用軟體工具和既定程式,對軟體所進行的測試活動。

對於前面提到,團隊面臨的第一個困難—即歷史需求時間跨度長,如果有自動化測試約束,則其演變一定是一個受控的過程。這恰恰說明了實施自動化測試有非常重要的意義。

團隊面臨的第二個困難,相對於熱補技術這種事後補救技術,自動化測試才是更根本性的質量保障手段。

年初有篇文章曾經發起過討論,矽谷的網際網路公司並不熱衷於熱補這類“黑科技”,而是更多關注利用自動化測試技術,讓應用在上線之前就有更好的質量保障。

第三個困難,需要提升研發效率和迭代頻率。表面上看,似乎和自動化測試並沒有太明顯的關係。

但隨著我們的深入思考,發現了一個奇妙的結論:自動化測試是提升迭代效率的關鍵,也是提升研發效率的有效手段。見圖1

0?wx_fmt=png
圖1 酒旅迭代週期時間分配分析

從上圖可以看到,每個迭代週期中,開發時間與測試時間的比例達到5:4。而回歸測試時間佔據了測試時間的50%。自動化測試手段可以大幅縮減迴歸測試的時間成本,因此可以大幅提高迭代的頻率!

如何實施自動化測試

明確了自動化測試的意義,下一步應討論如何實施自動化測試。作為團隊的重要技術專案,我們需要制定明確的目標。

如何評估自動化測試的收益

評估自動化測試的收益,需要明確短期和長期目標的設定。從實際收益來看,則需要明確“能否測出 bug”、“測試用例維護成本”、“減少了多少手工測試成本”。

覆蓋率指標則被當做過程管理的抓手,包括測試用例的覆蓋率和程式碼執行的覆蓋率。

  • 目標:

    • 短期目標:消滅SA級別的線上故障

    • 長期目標:減少75%的線上故障;發版頻率從月提高到周

  • 收益衡量方法

    • Bug的測出率(能不能測出來bug)

    • 測試用例的失效率(測試用例的維護成本高不高)

    • 減少了多少手工測試時間

  • 過程指標:

    • 測試用例覆蓋率(開發了多少自動化測試用例)

    • 測試的執行覆蓋率(程式碼行覆蓋率、程式碼分支覆蓋率)

明確了上面這些指標,我們在實施自動化測試的時候,就需要有意識的收集這部分的資料,用來評估自動化測試帶來的實際價值。

自動化測試的方法選型依據

明確目標和衡量方法之後,我們需要進行方法選型。Google曾經在《Google 測試之道》中介紹過,合理測試包括單元測試、整合測試、UI測試(見下圖),其佔比大概為7:2:1。

0?wx_fmt=png

然而,從我們設定的收益衡量方法來看,這並非收益最大的做法。佔比最高(70%)的單元測試,並不能測出多少 Bug。

根據我們的經驗,以使用者視角進行測試,更容易發現 Bug。因此,我們需要基於實際的業務形態,選擇對投入產出比最高的方案。首先我們看一下酒旅的業務形態,見下圖:

0?wx_fmt=png

其主要包含兩種頁面型別:資訊展示型頁面和互動邏輯型頁面。兩種頁面的關注點差異很大:資訊展示型通常只是將後端 API 返回的資料進行“簡單”的處理,並最終繪製在螢幕上。

其關注重點在於展示是否正確(UI控制元件的佈局,文字截斷、折行,等等)。

互動邏輯型頁面重點關注的是使用者操作帶來的邏輯處理,需要進行端到端的測試,即使用者操作產生了對服務端 API 的請求。

顯然,這兩種型別頁面的測試關注點並不相同,因而技術選型上也會有所差異。我們的技術選型方案如圖所示:

0?wx_fmt=png

對於互動邏輯型頁面,我們選擇了“面向UI介面”的整合測試方案。這種方案主要解決細粒度的程式邏輯校驗,這類頁面佔比較低(約20%)。

但是意義重大,一旦出現 Bug,很有可能是較嚴重的故障。因此對這一類頁面的測試也顯得尤為重要。

對於資訊展示型頁面,我們選取了UI截圖測試的方案,可以進行畫素級別的展示結果校對。截圖測試方案可以覆蓋大約80%的客戶端頁面,同時覆蓋成本也較低。

任何一個自動化測試的選型都會遵循以下的步驟:

  1. 設定上下文狀態(資料打樁、全域性初始化)

  2. 模擬使用者行為

  3. 校驗執行結果

下面我們就對資訊展示型和互動邏輯型頁面,使用自動化測試的三部曲的套路,實施測試。

互動邏輯型頁面的測試方法

對於互動邏輯型的頁面,測試的重點是邏輯細節,我們選取對 ViewModel 進行測試。

這裡有一個背景,我們在兩年前就開始積極實踐 MVVM(Model-View-View-Model) 和 FRP(Fuctional Reactive Programming)。

MVVM 帶給我們最大的好處就在於自動化測試。

當然,MVVM 只是使得測試變得更容易,但並不是實施自動化測試的必要條件。傳統的 MVC 模式,同樣可以進行細粒度的程式碼邏輯測試。

0?wx_fmt=png

如圖所示,基於 MVVM 或 MVP 的設計模式,測試會變得更容易。測試用例模擬檢視,訪問 ViewModel 或 Presenter,對業務邏輯進行驗證,既可以校驗應用的狀態,也可以校驗提交的後臺伺服器的資料(引數)。

//1. 設定測試資料(打樁)

[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request {    
   return [request.URL.path containsString: @"替換URL的路徑"]; } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) {    
   NSData *data = 要返回的資料    OHHTTPStubsResponse *fakeResponse = [OHHTTPStubsResponse responseWithData:data statusCode:200 headers:@{@"Content-Type" : @"application/json"}];    
   return fakeResponse; }]
//2. 模擬使用者行為

LoginViewModel* vm = [[LoginViewModel alloc] init];
//模擬輸入使用者名稱、密碼vm.userID = XXXX vm.password = XXXX//執行登入動作[vm.loginCommand execute:nil]
//3. 校驗登入結果

[vm.loginCommand.executionSignals.flatten subscribeNext:^(id x) {    expect(x).equal(@"LoginSuccess");    done(); }];

資訊展示型頁面的測試方法

我們選擇截圖測試方案對資訊展示型頁面進行測試。想要使用截圖測試方案有一個前提:就是除掉程式程式碼的因素,每次截圖都需要有唯一的結果。

這就對應了自動化測試三部曲的第一步,“設定上下文狀態(資料打樁、全域性初始化)”。

通常情況,資訊展示型頁面總是需要展示後臺API返回的資料,並且可能展示一些和使用者狀態相關的內容。

比如,使用者名稱、使用者裝置定位資訊(座標、地圖)、系統日期與時間,等等。

因此,在實施截圖測試方案時,第一步需要設定許多狀態,比如對後臺API的打樁和 Mock。

這裡建議將 Mock 程式碼進行一些封裝沉澱,因為它們很大概率會被其他 Case 複用。

第二步,模擬使用者操作。資訊展示型頁面的典型操作通常是載入->展示,和滾動一屏->展示。這裡我們選擇了 KIF 框架模擬使用者行為,滾屏操作十分容易。

第三步,進行截圖或圖片比對。這裡我們選用了 Facebook 開源的框架FBSnapShoot。程式碼如下:

//測試用例繼承於FBSnapshotTestCase

//1. 打樁 (與互動邏輯型頁面相同,不在贅述)
//2. 獲取需要比對的檢視
UIView* view = 獲取需要比對的檢視
//3. 截圖比較
FBSnapshotVerifyView(view, nil);

是不是簡單的有些不可思議?

未來展望

針對不同的業務型別,我們同時選擇UI截圖和UI介面整合測試的方案。使用這兩種方案仍都有較大的效率提升空間:

UI截圖方案的 Case 失效率較高我們需要用工具化、平臺化的方法提升Case維護效率。

  • 自測場景集中展示新需求的UI截圖,並且覆蓋主流機型的全部解析度。通過工具批量確認截圖的內容是否這確,可以顯著提升自測的效率和覆蓋率。

  • Case測試失敗場景當 Case 測試失敗時,集中展示全部執行失敗的Case。如果確實有 Bug,就點選“報Bug”按鈕;否則點選“更新截圖”按鈕。

  • 新裝置支援當出現新的裝置,比如 iPhone X,我們可以集中執行全部的截圖測試用例,一次性得到所有的截圖。這比手工跑一遍人工測試要高效的多

UI介面整合測試開發成本較高我們選取的業務場景,對質量有更高的要求,因此投入更多的人力實施自動化測試是符合投入產出比的。

針對這種場景,我們建議通過改進框架提高複用,提升校驗環節的效率。


近期熱文

TensorFlow 計算與智慧基礎

突破技術發展瓶頸、成功轉型的重要因素

Selenium 爬取評論資料,就是這麼簡單!

那些關於前端資料結構與演算法

突破技術發展瓶頸、成功轉型的重要因素


《GitChat 達人課:Selenium 自動化測試從零實戰

0?wx_fmt=jpeg

「閱讀原文」看交流實錄,你想知道的都在這裡

相關文章