版權聲明:本文由劉笑江原創文章,轉載請註明出處:
文章原文連接:https://www.qcloud.com/community/article/80html
來源:騰雲閣 https://www.qcloud.com/community算法
在 微信讀書 App 中,排版引擎負責解析 EPUB 或 TXT 格式的書籍源文件,將排版後的書籍內容如文字、圖像、註解等元素渲染至屏幕上,是最經常使用、最複雜的組件之一。xcode
而開發同窗對排版引擎的平常修改,可能影響了海量書籍的排版結果。對排版引擎代碼變動的測試,每每耗時多、難度大、容易漏測。本文介紹了爲解決測試的難題,如何逐步將人工測試步驟自動化,最終構建了一套微信讀書排版引擎自動化測試流程,以確保微信讀書排版引擎的質量。微信
爲了得到極致的閱讀體驗,產品同窗常常會提出細緻的排版需求,交給開發同窗修改。而排版引擎的修改,每每牽一髮動全身,可能致使書城上萬本書籍排版結果受影響。數據結構
舉個例子,有個需求是增長正文段落的 margin:
app
再舉個極端的例子,有個需求要把章節標題往右移動1個像素:
svn
那麼,如何確保微信讀書的排版質量?最開始,咱們用人工測試的方法來確保質量。函數
當開發按需求修改排版引擎、自測後,會把代碼提交到 svn,而後交給測試同窗進行測試。工具
測試同窗使用持續集成工具編譯打包,獲得排版引擎修改後的 App 安裝包;而後在兩臺設備安裝排版引擎修改前、後兩個版本的 App,同時打開須要測試的書籍,翻頁,對比,經過肉眼觀察排版差別是否符合預期。性能
人工測試方法比較耗時,須要打開每本書,一頁一頁地翻頁、對比,並且沒法覆蓋不少書籍,存在漏測的風險。
另外,經過人眼檢查兩臺設備上的排版結果有沒有差別,是很困難的任務,一是容易疲憊致使判斷失誤,二是對細緻的排版變動(如第二個例子)很難判斷是否符合預期。
爲何須要自動化測試?
前面提到,人工測試費時耗力,且容易漏測。
此外,排版需求的特色是細節多、變動快,且修改影響範圍大,全網書籍上萬本,沒法一一驗證。一旦出錯,直接影響口碑。這些因素都增長了人工測試的工做量和壓力。
除了精細化的排版需求會對排版引擎代碼作修改,在平常的維護中,也會重構排版引擎、修改排版引擎相關但不影響排版結果的代碼。每次重構、修改後,也會交給測試同窗驗證這次修改對排版結果沒有影響。因爲人工測試比較耗時、沒法一一驗證,每次重構排版引擎代碼壓力很大,輕易不敢改動。
還有一種狀況,是在開發其餘需求、修復缺陷時,意外地致使排版結果受影響。這種錯誤一旦發佈到現網,後果很嚴重。
因此,把人工測試流程自動化十分有必要。自動化之後,能夠大大減小人工測試的時間,同時方便開發同窗自測。開發同窗對排版引擎也能夠大膽重構、持續改進代碼質量。最終,達到確保排版引擎質量的目的。
首先,咱們要分析一下,在人工測試中,主要有哪些步驟?每一個步驟是否能自動化?
在人工測試中,對每次變動的測試,有步驟以下:
其中步驟 一、2 利用自動化測試工具是比較容易完成的。步驟 3 藉助算法可以使其自動化,會在後面詳細展開。步驟 4 自動化的難度比較大,可能須要藉助很是高階的人工智能完成,咱們把這個步驟交給測試和開發同窗。
那麼,如何完成步驟 3 的自動化,讓機器作人類的事情呢?咱們把它再細分紅三個步驟:
首先,須要找到一種機器能讀懂的數據表示,這種數據表示要既可以表示排版的結果、反映代碼的修改,也可以經過算法來對比,對比的結果要便於可視化的展現,方便開發、測試同窗判斷差別是否符合預期。
咱們的選擇有:
NSAttributedString,是從 EPUB、TXT 處理後獲得的中間數據,包括文字和排版樣式。這種數據結構比較抽象,沒有一種很好的差別計算方法、和差別結果可視化方法。
閱讀器屏幕截圖,位圖格式,藉助各類成熟的數字圖像處理算法,容易計算差別
考慮到 2 容易計算差別,可視化輸出效果較好,咱們選取閱讀器屏幕截圖做爲數據表示。
選擇了圖像做爲排版結果的數據表示,那麼如何對比圖像差別呢?
首先,咱們要選取圖像特徵,而後才能對比圖片差別。圖像的特徵,從視覺認知概念上,有低、中、高級特徵:
有了特徵後,咱們須要定義差別,就是兩個灰度圖像矩陣的距離函數,如:
咱們關心有多少像素點不一致,因此咱們這裏取 L0距離,即兩個圖像有多少個像素點不同,做爲差別衡量的指標。
當距離大於10時,咱們認爲這一頁的排版結果有差別,把它可視化輸出,給開發或者測試同窗做爲參考。
檢測到差別後,咱們把兩個圖像矩陣灰度化後相減,獲得一個新的矩陣,把它歸一化獲得差別圖像,如右圖所示:
人工測試步驟 二、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。
下面,將介紹咱們完整的排版引擎自動化測試流程。
首先,用戶須要肯定參數:待生成排版結果的 svn 版本範圍 r1~rn、書單、閱讀偏好設置(字體、縮進、主題模式)。把這些參數傳給腳本batch_scan.py
,而後自動化流程開始,腳本會執行如下步驟:
獲得排版結果後,執行腳本 batch_diff.py
,對相近的版本,每本書的每一頁經過 diffimg.py 對比,若是有差別,則輸出可視化的差別結果。
自動化流程結束後,咱們獲得排版結果差別,須要人工去檢查差別是否符合預期。
咱們以文件夾的形式組織展現差別的可視化結果:版本 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,輸出運行結果截圖,以插件的形式接入這一套自動化測試流程。
本文介紹了微信讀書排版引擎的平常修改時,人工測試所面臨的問題,以及爲何須要自動化測試的緣由。
而後本文分析了人工測試的流程,以及這些流程改形成自動化的可能性。
最後,介紹了咱們整套自動化測試流程,以及應用自動化測試之後所來的好處,最終達到確保微信讀書排版引擎質量的目的。