天天看點

小程式可測性能力建設與實踐

作者:閃念基因

本文整理自美團技術沙龍第77期《美團億級流量系統的品質風險防控和穩定性治理實踐》。作為一種終端産品生态,小程式在業界産品中占有非常重要的地位。本文從小程式的品質保障需求出發,分析小程式的測試難點,引出小程式可測性的基本概念,介紹美團到店研發平台針對小程式可測性改進的通用化方案。最後分享美團門票業務小程式測試工作的實踐經驗,本文旨在為讀者在小程式品質保障領域提供一些有價值的見解和啟示。

  • 1. 引言
  • 2. 小程式可測性介紹
    • 2.1 使用方式與效果
    • 2.2 接入方式
    • 2.3 實作原理
  • 3. 美團門票業務小程式測試實踐
    • 3.1 可測性落地
    • 3.2 業務實踐總結
  • 4. 總結與展望
  • Q&A

1. 引言

測試活動從本質上可以視為被測系統因為某個激勵産生相應的響應,并對這些響應進行全面檢測的過程。這個過程(激勵->響應->檢查)涉及到兩個角色:測試者以及測試對象,測試者執行激勵與檢查響應,由機器(程式)或者人來完成;被測對象接受激勵,産生響應。從這個過程來看:激勵可控,響應可觀,稱之為可測。以實際業務測試為例,修改緩存、網絡請求MCOK、頁面跳轉、使用者登入态設定等都屬于可測性能力。

小程式可測性能力建設與實踐

在未經過任何可測性改進的終端産品中,測試人員隻能通過UI互動,從UI界面觀察來完成最基本的品質保障。然而應用内部存在各種各樣複雜的邏輯、狀态,要進行更加深入的測試則需要對這些資訊進行介入與觀測。例如,在進行打點測試時,操作頁面後,需确認打點資訊是否被正常上報,這一過程通常依賴網絡代理調試工具來完成校驗。同樣,在使用者登入測試環節中,登入完成後,需要檢查緩存是否已正确記錄登入資訊,這要求具備緩存檢視的能力,這些展現了實際業務測試場景對可測性能力的需求。

整體而言,完備地構造出目标場景進行測試涉及到多個複雜的方面,同時觀測它是否符合預期也比較困難,如下圖所示。終端測試長期面臨着挑戰。為應對這些挑戰,我們以增強可測性為基礎,将其貫穿測試活動的始終,使得測試能更細粒度地檢查系統,提高測試深度和效率。

小程式可測性能力建設與實踐

作為終端産品的一種形态,小程式是運作在宿主應用(如微信、快手、百度等)之上的“輕應用”,在2017年由微信推出後發展迅速。由于小程式非常依賴于宿主應用環境,是以在測試過程中,除了面臨終端測試固有的難點外,它還存在一些特殊的影響因素。

從運作機制的角度來看,小程式的代碼邏輯運作在宿主應用提供的容器環境内,它無法直接控制宿主應用本身和手機系統,這在一定程度上增大了測試與可測性改進的難度。

小程式可測性能力建設與實踐

在目前的實踐中,針對小程式的測試主要存在以下幾種工具和政策:

  1. 采用如Charles、Fiddler等網絡代理工具進行HTTP/HTTPS請求和響應的代理分析與校驗。雖然這類工具适合進行資料包的抓取和分析,但它們通常無法深入小程式的内部架構,是以無法全方位控制或感覺應用的内部狀态。
  2. 運用圖像處理技術的自動化測試工具如Airtest進行測試,它們主要關注于界面層面的操作,未能觸及應用程式背後的邏輯處理,是以仍屬于“黑盒測試”的範疇。
  3. 利用微信官方提供的Minium小程式測試工具來執行更為精細的測試操作,能夠進行諸如API Mocking等内部控制。然而,該方法操作複雜,并依賴于微信開發者工具,而後者與真機環境之間存在一定差異,可能影響測試結果的準确性。
  4. 開發專用的自研調試面闆用以驗證程式邏輯和測試特定場景,但這些工具設計時常常專注于特定小程式,不易遷移至其他應用,而且它們通常不支援自動化測試流程。

綜上所述,盡管存在多種測試工具和方法,但目前尚缺乏一套綜合性的、易于使用的測試工具集,能夠全面提升小程式的可測性。

2. 小程式可測性介紹

小程式可測性能力建設與實踐

終端可測性能力全景圖

小程式可測性的目标在于建構一套全方位的通用小程式可測性能力集合。該體系無縫支援真機和模拟器環境,相容多端、多平台,并允許不同應用以低成本輕松接入。它能深入核心,為小程式提供全面而多元的可觀測性與可控性,覆寫應用界面、内部狀态、存儲等關鍵領域。這一體系旨在賦能測試者更便捷地應對複雜測試場景,顯著提高測試的效率與深入度。

經過了長期的建設積累,目前我們已經建構了一套比較全面的終端可測性能力集,包含Android、iOS、小程式、Web等技術棧。其中小程式由于系統的結構特殊性,可測性能力相對其它端會有一些不同。小程式可測性主要包括業務邏輯可測性、應用可測性、系統&裝置可測性三個層級,在每個層級中包含多個垂直的細分方向,除了支援多技術棧的公共可測性能力,還提供了如AppData、宿主應用資訊可觀可控等特有能力。下面以幾個典型能力說明小程式可測性使用方式與效果。

| 2.1 使用方式與效果

在實際的手工以及自動化測試工作中,小程式可測性能力能夠很友善的使用,并在多個場景下發揮了重要的作用。

2.1.1 手工測試

下面将以緩存管理、頁面跳轉功能為例介紹小程式在手工測試中的使用方式以及效果。

在實際的測試工作中,會結合Lyrebird使用小程式可測性,Lyrebird是美團到店研發平台自研的終端測試工作台,包含終端狀态資料管理、網絡請求代理與Mock、缺陷記錄、自定義插件擴充等能力。同時它還提供了圖形化操作界面,是手工與自動化測試中使用可測性能力的入口。

在小程式接入可測性能力SDK之後,可以通過可測性SDK提供的掃碼功能與Lyrebird建立連接配接,後續就可以通過Lyrebird在PC端利用可測性對小程式進行控制以及觀測。

小程式可測性能力建設與實踐

緩存管理

我們可以通過緩存管理功能驗證依賴緩存的業務邏輯正确性,如表單資訊\使用者資訊暫存到緩存功能等。

  • 如下圖所示,1處為緩存編輯框,展示目前選擇裝置上的小程式所有的緩存資訊,并對這些緩存進行管理,支援批量的增删改。
  • 2處展示目标小程式的緩存變更事件資訊,包括在該頁面對緩存的編輯以及小程式自身内部對緩存的增删改操作事件,會随着事件的觸發實時更新。
小程式可測性能力建設與實踐

頁面跳轉

頁面跳轉是小程式業務測試中重度使用的能力,可以利用該功能跳轉到如表單頁,商品詳情頁等中間頁面,不再需要從首頁一步一步操作進入目标被測頁面,減少測試前置準備工作,具體可以在該Lyrebird頁面中輸入頁面路徑進行跳轉。

小程式可測性能力建設與實踐

2.1.2 自動化測試

将可測性能力結合Lyrebird應用于自動化測試。如通過頁面跳轉能力直達測試場景,然後利用通過可測性錄制的頁面狀态資料進行場景狀态還原後進行頁面渲染,擷取頁面上的資料/布局展示,最後将實際運作圖和預先設定好的頁面基準圖進行對比,提供渲染的差異結果,進行視覺DIFF測試。

這類“視覺測試”以頁面為機關,通過深度連結跳轉技術配合一系列終端應用本身的可測性改造,直達測試場景,并通過圖像處理技術如長圖融合、圖像增量對比和文本識别能力進行視覺DIFF測試。
小程式可測性能力建設與實踐

可測性建設的是對應用内部狀态的可觀可控能力,對于任何測試方法,隻要涉及應用内部,可測性都能發揮重要作用。比如在健壯性測試中通過可測性構造破壞性異常場景,或者在功能測試中模拟小程式不同的進入方式(如二維碼、視訊号、搜尋等)來測試所有可能的使用場景下小程式的運作情況。

小程式可測性能力建設與實踐

| 2.2 接入方式

小程式可測性能力SDK被封裝為一個NPM包,在小程式源代碼或者編譯産物項目中引入此NPM包,便可實作可測性能力的接入,無需進行額外适配工作。

跨平台運作

除了對微信小程式的支援之外,小程式可測性能力SDK通過內建一個擴充卡(Adapter)将能力擴充到多宿主應用,包括美團、支付寶、快手、百度等平台的支援。這些平台的基礎庫API與微信類似,擴充卡會根據不同平台的特點,對代碼進行相應的調整,包括基礎庫API、前端文法或檔案類型等,以保證在各個平台上的相容性和一緻性,實作跨平台運作。

| 2.3 實作原理

小程式可測性實作的核心思路是通過JavaScript Hook的方式,在小程式JavaScript Runtime中對如微信小程式JS基礎庫、業務公共基礎元件等目标子產品進行透明化介入,實作對其内部的可觀可控。在此之後,通過可測性SDK内的中控與外部建立網絡連結,進而實作在遠端對小程式内部狀态與功能的可觀可控。

JavaScript Hook介紹

JavaScript Hook基于JavaScript的動态特性,有以下方法:

函數Hook:直接覆寫或修改原函數:

let _originAlert = alert;  // 儲存原函數
alert = function () {
  console.log('alert執行開始');
  _originAlert.apply(this, arguments); //執行原函數
  console.log('alert執行結束');
}           

對象屬性Hook:通過Object defineProperty定義新的或直接修改某個對象的屬性,如修改Getter/Setter方法,控制對某個對象的擷取/設定流程。

Object.defineProperty(document, 'cookie', {
  set: function(val) {  // 控制cookie的設定流程
    console.log('獲得cookie: ', val);
    currentCookie = val;
    return val;
  },
  get: function() {  // 控制cookie的擷取流程
    return null;
  }
});           

原型鍊Hook:修改原型鍊上的資料,如String、Date。

let _originalGetTime = Date.prototype.getTime;  // 儲存原型鍊原方法
Date.prototype.getTime = function() {
  console.log('getTime has been called'); 
  return originalGetTime.apply(this, arguments); //執行原方法
};           

Proxy對象:建立代理模式替代原始對象,可以重新定義擷取、設定和定義屬性等基本對象操作。

// 建立Proxy有兩個參數:
// target:要代理的原始對象
// handler:定義哪些操作将被攔截以及如何重新定義被攔截操作的對象
let handler = {
  get: function(target, prop) {
    console.log(`擷取 ${prop}`);
    return target[prop];
  },
  set: function(target, prop, val) {
    console.log(`設定 ${prop} 值為 ${val}`);
    target[prop] = val;
    return true;
  }
};

let proxy = new Proxy(window, handler);

proxy.test = 'test';     // 輸出: Setting test to test
console.log(proxy.test); // 輸出: Getting test
                         //      test   
                                    

靜态Hook:小程式建構時在特定檔案中直接修改其JavaScript源代碼。

其他方式這裡就不詳細展開了。

可測性SDK的大體可分為四層:

  • 通信層:與外部進行通信,負責指令和資料與遠端(如Lyrebird)的雙向流動。
  • 指令分發層:對通信層接收到的參數指令進行解析,依次調用控制小程式相關狀态的功能層子產品。
  • 功能層:實作小程式特定功能可觀可控的業務邏輯,包括UI、網絡請求、存儲、應用狀态等子產品,實作如請求代理與修改、切換登入态或者控制緩存可測性功能。
  • Hook層:實作對實際邏輯子產品狀态和方法的透明化介入。由于小程式應用内部的狀态/資料與開發者代碼相關聯,Hook層通過JavaScript Hook對宿主應用基礎庫、公共元件、業務特定邏輯三種類型的功能子產品進行攔截介入,使得其狀态/資料可觀和可控,為功能層提供實作基礎。Hook層一般需要先于業務代碼加載,保證攔截的有效性。
  • 宿主應用基礎庫。通用性改造,對小程式容器提供的系統級接口進行介入,如網絡請求、地理資訊等。
  • 公共元件。元件級通用,如美團的公共登入元件,對其進行改造後,接入登入元件的小程式都能夠使用相應的可測性能力,比如切換登入态/模拟登出等能力。
  • 業務特定邏輯。某個小程式特有的業務邏輯,通過可測性SDK提供的API對這些邏輯進行改造後以插件形式內建定制化能力。

下面将以網絡請求可觀可控為例介紹小程式可測性的實作原理。

網絡請求代理

當外部希望控制小程式設定網絡代理時,整體流程如下:

小程式可測性能力建設與實踐
  1. 外部(人/機器)首先通過HTTP/WebSocket方式傳遞包含設定小程式請求代理的指令,如圖即攔截小程式發送的請轉發到127.0.0.1:1234代理伺服器;
  2. 可測性SDK在通信層接收相應的指令後。将其傳遞給指令分發層。在指令分發層中,收到指令後進行解析,并按預定規則對指令執行進行編排,确定執行順序;
  3. 指令分發層按編排順序調用功能層設定網絡代理并傳入開啟狀态和代理伺服器位址參數,功能層通過修改這兩個變量,控制Hook層對請求API的攔截,進而改變請求代理的狀态;
  4. Hook層攔截微信基礎庫裡wx對象的request方法,如下圖代碼所示,分為以下流程

a.儲存wx.request原始方法的引用(3行),并通過Object.defineProperty将wx對象設定為可寫狀态(4-8行);

b.将wx.request修改為Hook的新方法。新方法的入參與原始wx.request一緻,包括請求頭、請求位址、響應體等,是以可以對這些參數進行修改(12行),比如替換請求域名、增加請求頭、修改響應體資料等;

c.最後用修改後的參數使用原始方法進行執行(13行)。

Hook層通過mockStatus和mockUrl兩個變量控制到小程式是否被代理以及代理伺服器位址(19-22行),當開發者代碼中使用wx.request發起請求時,會先經過Hook指向的新方法。如果被設定代理,請求位址将會根據代理伺服器協定進行修改,進而使得請求被代理。

小程式可測性能力建設與實踐

3. 美團門票業務小程式測試實踐

在到店衆多應用了小程式可測性能力的業務中,美團門票業務從2021年開始即參與了小程式可測性建設,目前在門票品質保障工作中,可測性相關能力深度應用在新需求測試、回歸測試、線上巡檢等各種類型的測試活動中。

| 3.1 可測性落地

下面通過門票業務一個具體的新需求測試例子來介紹可測性如何在測試活動中進行落地。

需求背景

使用者從商品詳情頁進入到填單頁,在選擇日期、數量或填寫遊玩人等資訊後,為了減少使用者的操作,再次進入該填單頁需要保持之前填寫的資訊不變。

小程式可測性能力建設與實踐

操作路徑劃分

該過程需要經過以下步驟:進入填單頁 —> 打開價格月曆彈層,選擇相應的日期 —> 添加數量 —> 填寫或者選擇遊玩人 —> 點選傳回退出填單頁 —> 再次進入填單頁,檢視它目前的狀态。我們選擇對緩存進行可測性改進,依靠指令資料驅動+内部方法調用來達到同等UI操作的效果,保障此類場景測試的穩定性并提高執行效率。

技術實作

整體通過緩存實作。在進入填單頁時,首先會讀取小程式上的緩存并渲染;在選擇日期、數量和遊玩人時,分别對相關資訊進行暫存;在退出填單頁時,将這些暫存的資料寫入緩存。

小程式可測性能力建設與實踐

測試分析

由于進入填單頁需要讀取緩存進行渲染,是以測試過程中首先應從UI上進行驗證,判斷第二次進入的日期、數量和遊玩人是否與上一次進入時選擇的狀态一緻;其次還應從資料上進行驗證,即進入填單頁有“讀”緩存的動作;在退出填單頁時,需要将暫存的資料寫入緩存,是以測試過程中應驗證資料能正确地寫入緩存,而且緩存裡有正确的值。

小程式可測性能力建設與實踐

可測性能力實踐落地

  • 通過可觀校驗“寫”的正确性。對于“寫”,驗證緩存的寫入動作,并且寫入緩存的資料是正确的。緩存的可觀性改造能夠将“寫”的動作、“寫”的目前值以及目前緩存具體資訊,進行上報,這樣就可以自動化校驗目前操作後是否緩存值是否發生了正确的變化,以此完成對緩存“寫”的校驗。
小程式可測性能力建設與實踐
  • 通過可控校驗“讀”的正确性。對于“讀”,首先驗證UI能夠正确展示,其次從資料上驗證有緩存的“讀”動作。由于測試緩存必須經曆選擇日期、選擇數量、選擇遊玩人,傳回退出填單頁等多個步驟。測試路徑較為繁瑣,是以,對緩存的可控性改造後,傳入相應的配置指令(如2.2部分介紹),控制緩存中的資料,直達被測頁面和狀态,并通過自動化測試比對目前運作的頁面和頁面基準圖,判斷它是否正确被渲染,以此分别從資料和UI上完成對緩存“讀”的校驗。
小程式可測性能力建設與實踐

門票業務在小程式測試上目前已經落地多種可測性能力,如下圖所示,包括控制頁面跳轉、請求代理、控制登入、日志上報、隐私治理、前後端環境、錄制回放、自動化互動控制等都在門票測試活動中有相應的落地,發揮着非常重要的作用。

小程式可測性能力建設與實踐

| 3.2 業務實踐總結

門票業務借助可測性改進使得測試的覆寫更加全面,目前30%+的測試場景依賴于可測性能力進行建構。在美團小程式和點評小程式的門票頻道以及門票獨立小程式上均有上百個自動化測試用例,頁面覆寫率已經達到100%,場景覆寫程度達到80%+。這些測試用例在門票新需求測試、回歸測試等各個階段都會觸發自動執行,累計已輔助發現上百個有效問題。

4. 總結與展望

美團核心本地商業/到店研發平台從2021年開始系統化建設小程式可測性,到目前融入到店終端測試工具鍊以及品質保證體系之中,通過具備擴充性的通用能力架構,融合手工和自動化測試,貫穿測試活動始終。未來我們還将持續關注于基礎可測性能力的穩定性,聚焦具備更多業務特性的可測性能力建設。

Q&A

Q:代理邏輯如果有Bug會不會影響比較大

A:代理邏輯本身很簡單,出錯機率不大。進行Hook時,會有異常監控能力以及相應的兜底政策,即使出問題,也盡量降低對業務實際使用的影響。

Q:可測性SDK需要對業務代碼進行改造嗎?

A:不需要,可測性SDK對于業務應用是透明的。

Q:Lyrebird項目和小程式可測性SDK的關系是什麼?

A:Lyrebird與小程式可測性是兩個獨立的項目。小程式可測性SDK是以一個NPM包的形式實作的,在小程式裡安裝NPM包,即可使小程式具有可測性。Lyrebird可以與小程式可測性SDK的通信接口進行連接配接,然後使用者可通過Lyrebird中小程式可測性頁面使用小程式可測性能力。

Q:針對小程式可測試性能力建設與實踐,我想問下,如果我們要用你們的測試工具,需要做什麼适配嗎?

A:不需要進行額外适配,最終的呈現會是NPM包形式,在産物裡安裝就可以接入我們的可測性能力,可以對它進行控制。

Q:生産環境會接入可觀測SDK嗎?如果接入對性能有多大影響?

A:首先是對它的性能的影響,我們實際上是對小程式裡的基礎庫的API或者一些狀态資料進行了攔截,會對性能産生一定的影響,但目前這個影響範圍對業務來說比較小,是可接受的。生産環境的不會引入可測性SDK,是以不會對線上品質造成影響。

Q:小程式可測性有不适合使用的場景?

小程式可測性主要針對小程式前端手工與自動化場景進行能力提升,它是具備一套通用可擴充架構,可以按照業務需求低成本進行可測性能力擴充,然而,存在特定情況下其适用性受限:首先,由于運作環境的限制,針對宿主應用如微信或支付寶自身的可測性需求,小程式的可測性無法支援。此外,小程式可測性專注于終端測試,是以對于那些需求後端服務鍊路驗證的場景,并不适用,需配合針對性工具使用。

作者:到店研發平台

來源-微信公衆号:美團技術團隊

出處:https://mp.weixin.qq.com/s/NeCQUwfyrKz5VKE_E-hg_g

繼續閱讀