歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐干貨哦~
在 微信讀書 App 中,排版引擎負責解析 EPUB 或 TXT 格式的書籍源文件,將排版后的書籍內容如文字、圖像、注解等元素渲染至屏幕上,是最常用、最復雜的組件之一。
而開發同學對排版引擎的日常修改,可能影響了海量書籍的排版結果。對排版引擎代碼變更的測試,往往耗時多、難度大、容易漏測。本文介紹了為解決測試的難題,如何逐步將人工測試步驟自動化,最終構建了一套微信讀書排版引擎自動化測試流程,以確保微信讀書排版引擎的質量。
一.背景
1.排版引擎日常修改
為了獲得極致的閱讀體驗,產品同學經常會提出細致的排版需求,交給開發同學修改。而排版引擎的修改,往往牽一發動全身,可能導致書城上萬本書籍排版結果受影響。
舉個例子,有個需求是增加正文段落的 margin:
再舉個極端的例子,有個需求要把章節標題往右移動1個像素:
那么,如何確保微信讀書的排版質量?最開始,我們用人工測試的方法來確保質量。
2.人工測試方法
當開發按需求修改排版引擎、自測后,會把代碼提交到 svn,然后交給測試同學進行測試。
測試同學使用持續集成工具編譯打包,得到排版引擎修改后的 App 安裝包;然后在兩台設備安裝排版引擎修改前、后兩個版本的 App,同時打開需要測試的書籍,翻頁,對比,通過肉眼觀察排版差異是否符合預期。
人工測試方法比較耗時,需要打開每本書,一頁一頁地翻頁、對比,而且無法覆蓋很多書籍,存在漏測的風險。
另外,通過人眼檢查兩台設備上的排版結果有沒有差異,是很困難的任務,一是容易疲憊導致判斷失誤,二是對細致的排版變更(如第二個例子)很難判斷是否符合預期。
為什么需要自動化測試?
前面提到,人工測試費時耗力,且容易漏測。
此外,排版需求的特點是細節多、變更快,且修改影響范圍大,全網書籍上萬本,無法一一驗證。一旦出錯,直接影響口碑。這些因素都增加了人工測試的工作量和壓力。
除了精細化的排版需求會對排版引擎代碼做修改,在日常的維護中,也會重構排版引擎、修改排版引擎相關但不影響排版結果的代碼。每次重構、修改后,也會交給測試同學驗證此次修改對排版結果沒有影響。由於人工測試比較耗時、無法一一驗證,每次重構排版引擎代碼壓力很大,輕易不敢改動。
還有一種情況,是在開發其他需求、修復缺陷時,意外地導致排版結果受影響。這種錯誤一旦發布到現網,后果很嚴重。
所以,把人工測試流程自動化十分有必要。自動化以后,可以大大減少人工測試的時間,同時方便開發同學自測。開發同學對排版引擎也可以大膽重構、持續改進代碼質量。最終,達到確保排版引擎質量的目的。
二.如何自動化測試?
首先,我們要分析一下,在人工測試中,主要有哪些步驟?每個步驟是否能自動化?
在人工測試中,對每次變更的測試,有步驟如下:
- 需要把變更前、變更后的 App 包安裝到兩台設備
- 打開 App,登錄,把要測試的書購買、加入到書架
- 打開要測試的書,設置排版偏好,翻頁,用眼睛查看屏幕上的排版結果,對比屏幕中的排版結果是否有差異
- 如果有差異,根據需求判斷差異是否符合預期
其中步驟 1、2 利用自動化測試工具是比較容易完成的。步驟 3 借助算法能夠使其自動化,會在后面詳細展開。步驟 4 自動化的難度比較大,可能需要借助非常高階的人工智能完成,我們把這個步驟交給測試和開發同學。
那么,如何完成步驟 3 的自動化,讓機器做人類的事情呢?我們把它再細分成三個步驟:
1. 獲取排版結果的數據表示
首先,需要找到一種機器能讀懂的數據表示,這種數據表示要既能夠表示排版的結果、反映代碼的修改,也能夠通過算法來對比,對比的結果要便於可視化的展示,方便開發、測試同學判斷差異是否符合預期。
我們的選擇有:
- NSAttributedString,是從 EPUB、TXT 處理后得到的中間數據,包括文字和排版樣式。這種數據結構比較抽象,沒有一種很好的差異計算方法、和差異結果可視化方法。
- 閱讀器屏幕截圖,位圖格式,借助各種成熟的數字圖像處理算法,容易計算差異
考慮到 2 容易計算差異,可視化輸出效果較好,我們選取閱讀器屏幕截圖作為數據表示。
2. 對比圖像差異
選擇了圖像作為排版結果的數據表示,那么如何對比圖像差異呢?
首先,我們要選取圖像特征,然后才能對比圖片差異。圖像的特征,從視覺認知概念上,有低、中、高級特征:
- 低級特征:如像素域、頻率域、ImageHash
- 中級特征:如 sobel 邊緣特征
- 高級特征:抽象視覺概念,比如從 CNN 算法訓練得到的標簽,如車、槍、球
這里我們希望每個像素的差異都能檢測到,所以選取像灰度化處理過的圖像矩陣作為特征。
有了特征后,我們需要定義差異,就是兩個灰度圖像矩陣的距離函數,如:
- L0,表示兩個灰度圖像矩陣之間,不一致的像素點的個數
- L1,曼哈頓距離或棋盤距離,不一致像素點差值的絕對值之和
- L2,不一致像素點差值的平方和
我們關心有多少像素點不一致,所以我們這里取 L0距離,即兩個圖像有多少個像素點不一樣,作為差異衡量的指標。
當距離大於10時,我們認為這一頁的排版結果有差異,把它可視化輸出,給開發或者測試同學作為參考。
3. 可視化輸出
檢測到差異后,我們把兩個圖像矩陣灰度化后相減,得到一個新的矩陣,把它歸一化得到差異圖像,如右圖所示:
三.通過 scheme 生成排版結果
人工測試步驟 2、3 的書籍購買、加入書架、打開書籍、翻頁、截圖等任務,可以利用 Instrument UI Automation 自動測試腳本來模擬人工點擊來完成任務。
但是考慮到 Automation 模擬翻頁、截圖速度慢,且 UI 變更頻繁導致 Automation 腳本后續維護麻煩等問題,所以我們通過提供一個測試 scheme 接口來完成這個任務。
在 App 設置彩蛋的『執行 Scheme 頁面』中,輸入 scheme 並執行后,App 會在后台對指定書籍購買、加入書架、排版、生成排版結果截圖,並把結果保存在本地磁盤。用戶也可以選擇 AirDrop 到 Mac 上。
運行scheme
scheme 格式如下:
weread://typeset?books=三體,喬布斯傳,失控,1984,烏蘭拖拉機簡史&indent=1&fontSize=2&font=2&theme=3&folder=f1223
輸出排版結果到目錄/Libary/[vid]/[folder]/[bookId].zip
@param books 需要排版的書單
@param indent 0首行不縮進 1首行縮進,默認0
@param fontSize 1,2,3,4,5,6,7 字體大小,默認4
@param font 字體 1系統字體 2 3 4 為對應選項字體,默認1
@param bgcolor 背景顏色 1白 2黃 3綠色 4夜間,默認1
@param folder 輸出文件夾名,默認"cropImage"
通過這個 scheme,在真機或者模擬器都可以隨時得到排版結果,而且速度比模擬翻頁要快10x。
四.自動化測試流程
下面,將介紹我們完整的排版引擎自動化測試流程。
1. 生成排版結果
首先,用戶需要確定參數:待生成排版結果的 svn 版本范圍 r1~rn、書單、閱讀偏好設置(字體、縮進、主題模式)。把這些參數傳給腳本batch_scan.py
,然后自動化流程開始,腳本會執行以下步驟:
- 在指定 svn 版本范圍內,找出排版引擎有變更的版本,checkout
- 對每個 checkout 的版本,用 xcodebuild 編譯項目,安裝到模擬器
- 通過 Instrument 的 UI Automation 腳本,打開模擬器,運行微信讀書App,進入到測試彩蛋頁面:執行 scheme,生成排版結果
- 把結果從模擬器移動到指定的目錄下
2. 生成排版結果差異
得到排版結果后,執行腳本 batch_diff.py
,對相近的版本,每本書的每一頁通過 diffimg.py 對比,如果有差異,則輸出可視化的差異結果。
3. 人工檢查差異
自動化流程結束后,我們得到排版結果差異,需要人工去檢查差異是否符合預期。
我們以文件夾的形式組織展示差異的可視化結果:版本 r1(修改前)與 r2(修改后),對書籍 book1 排版差異可視化結果,保存在文件夾 diff_result_r1_r2/book1 中。
可視化結果圖像中,深色字體是 r1 (修改前)的排版結果,淺色字體是 r2 (修改后)的排版結果。
另外,排版性能變化也納入了監控。
五.自動化測試的優勢
自動化流程的建立,使排版引擎的測試時間縮短了 95%,測試期間無需人工干預,對比數據如圖:
例如,人工測試一本 550頁的 《哈利波特與被詛咒的孩子》需要約 20 分鍾,而自動化測試腳本掃描、對比差異只需 22 秒(不含編譯時間);人工測試 10 本書籍,用時約 3 小時,而自動化測試用時約 4.9 分鍾;人工測試 100 本書籍需 33 小時,而自動化測試用時約 50 分鍾。
除了大大減少人工測試的時間,開發同學借助自動化測試工具,能大膽重構代碼,通過自動化測試來確保重構不影響排版結果,擁抱快速變更的需求。
隨着自動化測試覆蓋的變更版本、測試的書籍數量越來越多,帶來的收益越大。
借助自動化測試流程,對於任何代碼修改而導致樣本書籍、每一頁、每個像素點的排版結果變更,都能夠納入我們的監控,最終達到確保微信讀書排版引擎質量的目的。
六.未來工作
目前,自動化測試工具已經投入使用。未來會持續優化、增加特性,以滿足測試、開發同學的需求。
未來工作包括但不限於
郵件通知:執行腳本得到結果后,如果兩個版本之間的排版結果有差異,通過郵件通知相關同學;另外,排版的性能對比結果也可以生成一份報告,通過郵件通報。
運行速度優化:目前對 20 本書生成排版結果,耗時約 10 分鍾,對比耗時約 2 分鍾。可以進一步優化運行速度,爭取覆蓋更多樣本書籍
支持微信讀書安卓版
嘗試應用在其他模塊:對運行預期結果相對固定、測試代價大的功能模塊,可以通過支持測試 scheme,輸出運行結果截圖,以插件的形式接入這一套自動化測試流程。
七.總結
本文介紹了微信讀書排版引擎的日常修改時,人工測試所面臨的問題,以及為什么需要自動化測試的原因。
然后本文分析了人工測試的流程,以及這些流程改造成自動化的可能性。
最后,介紹了我們整套自動化測試流程,以及應用自動化測試以后所來的好處,最終達到確保微信讀書排版引擎質量的目的。
問答
REST API的自動化測試如何實現?
相關閱讀
AI 精彩視頻剪輯:戰術競技類游戲直播
嘗試改進微信讀書個性化推薦:一個基於 CTR 預估的方法
【騰訊TMQ】基於模型的自動化測試工具:GraphWalker
【每日課程推薦】機器學習實戰!快速入門在線廣告業務及CTR相應知識
此文已由作者授權騰訊雲+社區發布,更多原文請點擊
搜索關注公眾號「雲加社區」,第一時間獲取技術干貨,關注后回復1024 送你一份技術課程大禮包!
海量技術實踐經驗,盡在雲加社區!