【騰訊TMQ】從插件重構看如何提升測試質量與效率

作者:廖億富

團隊:騰訊移動品質中心TMQ

導讀

幾個月前技術側發起了一輪手機管家小火箭的重構,目的是爲了更好地梳理小火箭的代碼架構邏輯,方便以後更好地提高開發效率和開發質量。

下面將從測試的角度爲大家一一剖析如何利用各種手段提高測試的質量與效率。

1 架構分析

重構的架構進行了分層設計,分爲了4層次:UI展示層、業務邏輯層、數據層和接口層。這樣子方便了代碼的開發、維護,同時對於測試人員對代碼分析、分層測試也提供了很多的便利,使得分層測試存在了很大的可能性。

2 測試分析

重構並不如新功能的開發,對於開發和測試人員來說,毋庸置疑的是必須熟悉重構前的功能,這樣子才能夠更好地進行業務開發和測試,否則會造成一些功能上的缺失和漏測的現象出現。同時如何能夠快速進行新舊功能的測試驗證,也是值得測試人員思考的地方。

2.1 架構與測試技術分析 ##

在熟悉插件架構和業務邏輯的可知,技術架構採用了分層設計的理念,那對於測試而言,是不是也可以進行一些分層設計的測試方式來進行測試呢。首先,對小火箭插件進行大體上的梳理。

從上圖可以剖析出我們需要的測試點與需要的一些測試技術:

(1)對於接口,我們可以利用模擬插件間的接口進行驗證。

(2)對於UI展示方面,我們可以利用手工測試或者ui自動化方式進行驗證。但是小火箭的UI主要是小火箭皮膚,涉及到皮膚拖動、發射等效果,利用ui自動化的方式難捕捉,所以採取了最土的方法:手工測試。

(3)對於業務邏輯和數據處理,我們可以利用單元測試的手段進行更深入的測試。

(4)對於調用外部接口,我們可以利用Hook進行模擬外部數據,方便更好地進行測試。

2.2 測試策略分析

經過對新功能與不變功能的分析,小火箭重構主要修改點是小火箭皮膚與邏輯的改造。對於不變功能可以採取提前測試接入(單測、插件間接口測試、UI功能測試),而對於新功能則跟隨技術架構與開發進度進行測試驗證。

3 插件間接口測試

插件的接口主要是爲了暴露接口給其他插件,方便與其他插件進行通信。以小火箭接口A爲例:

對於插件間的接口測試,我們把小火箭當成一個黑盒子,只需要關注接口入參(必填、選填)和出參的正確性,對於被測對象插件內的邏輯可以通過其他手段進行測試驗證。

Ø 接口協議分析:

接口文檔:從接口文檔中可知該接口有入參也有RESULT返回值,測試該接口時可以對返回值的結果進行校驗。

Ø 插件間測試用例設計:

用例設計主要分正常用例與異常用例(唯一標識、非空和長度校驗等)。

Ø 插件間測試用例執行:

利用pitest模擬插件發送請求,獲取返回值並校驗,同時校驗是否入庫成功。

插件的外部接口測試類似於上面的情況可以利用自動化方式每日進行監控,而有些接口是無返回值和難校驗的,可以利用模擬接口發現+人工驗證的方式進行驗證,同樣可以做到事半功倍,提高測試的效率。

4 單元測試

程序員要對自己編寫的代碼負責,不僅要保證它能通過編譯,正常地運行,而且要滿足需求和設計預期的效果。單元測試正是驗證代碼行爲是否滿足預期的有效手段之一。

做單元測試,除了需要深知單測方法、邏輯等知識外,還需要特別熟悉每個方法代表的意義和執行的業務邏輯。在這裏就不介紹單測的一些方法,僅從個人角度覺得有意思的三個方面說說單元測試的使用場景。

4.1 private私有方法的測試

測試Java私有方法之前的思路是通過把目標類的私有方法修飾符private修改爲public,或者將private在代碼裏面加public方法來調用私有方法,這兩種方式都是需要源程序的代碼,會造成代碼同步與維護難的問題。

經過查找,可以通過Java反射的方式達到private方法的測試。反射中的getDeclaredMethod()可獲取公共、保護和默認(包)訪問和私有方法,但不包括繼承的方法。

以getDemo(int type)這個方法來講如何進行private測試。

根據代碼可知:mModelList是已保存的事件list,根據傳入的事件類型進行遍歷。所以,在進行單測用例設計時,需要mock住mModelList模擬事件List,通過getDeclaredMethod進行private方法的調用。詳細單測代碼如下:

4.2 Java異常代碼走讀與測試

異常是阻止當前方法或作用域繼續執行的問題。雖然Java中有異常處理機制,但是絕不能用“正常”的態度來看待異常。

Throwable是Java種所有錯誤或異常的超類,包括了Error與Exception。Error是擁有指示合理的應用程序不應該試圖捕獲的嚴重問題,Exception它指出了合理的應用程序想要捕獲的條件。

常見的運行時Exception有如下10種:

案例分析:feature2RecoModel類代碼走讀與測試

通過代碼走讀/異常測試可以發現feature2RecoModel方法如果adModel.text1非數字,通過Integer.valueOf會拋NumberFormatException,會造成手管crash。所以大家在做代碼走讀時,可以留意Exception有沒有進行try-catch-finally/throws,否則很可能出現crash。

注:Integer.valueOf(str or num) 是把一個數字或者一個字符串轉化爲Integer類型的數據。

大家在代碼走讀/異常測試時可以關注異常的觀察與測試,很容易可以發現代碼中存在的Crash問題。

4.3 與業務邏輯結合測試

看下面checkDemo的代碼是沒有什麼問題的,就是判斷有沒有本地對應的事件而已。

如果只是跟隨開發設計代碼的邏輯來設計用例,而不思考使用場景,是很難發現業務層次的問題,同時也對測試人員提出了更高的要求:居要懂架構、代碼邏輯,更要懂每個方法的業務邏輯。

Ø 業務流程分析:

經過業務流程分析知道checkDemo的用處,分析Model數據(結構如下)可以知道有效的Toast事件是與showCount、maxShowCount和endTime緊密相關的。

Ø 用例設計與測試驗證:

接着我們來設計checkDemo的單元測試用例驗證邏輯:Model(過期時間<當前時間)塞入modelMap->調用checkDemo測試->結果判斷。

所以,單元測試不單單是代碼規範,代碼crash等異常,更關鍵的是要測試人員懂得每個方法代表的意義,才能夠更好地進行邏輯層的測試。

5 測試人員如何提高協作能力

小火箭是由技術側發起的重構,首先開發對新的架構進行梳理,測試側對之前用例進行整理,在前期就保證了產品、設計、開發、測試與運營在整理功能上保持了一致統一性,同時也確定了修改點和影響範圍。

整理了新舊功能,測試人員首先在舊功能上進行入手,對舊功能從插件接口、內部接口等方面進行測試用例準備,提前進行用例的測試。

開發人員在開發過程中,每天將代碼update到svn,第二天測試人員就對相應的接口進行用例設計與接口測試,與開發保持同步,及時發現代碼層的問題。

在提測前組織了一輪的冒煙測試,提測後利用自動化+手工測試的方式不到1天就完成了所有功能的迴歸驗證+渠道包上線前。大大地提高了測試在整個週期中所佔用的時間。

6 測試效果

小火箭渠道包已成功發佈,讓我們回顧一下測試方面的效果。

第一,從bug數量上來看:邏輯層的bug攔截率爲100%,其中利用白盒+插件接口+代碼走讀發現的問題有7個,冒煙測試18個,功能測試未發現問題。

第二,功能測試在開發提測後,僅花費了<1天的時間過功能測試+上線前的測試,大大減少了功能測試在整個重構(1個月左右)中的時間佔比。

對於重構的項目,我覺得可以從研發的各個階段入手,提高與各個角色的協同,可以更快地進行產品開發與測試的迭代。而對於測試技術、測試方法這個,可以利用被測對象的特性進行選型,怎麼有用怎麼方便就怎麼來。

思考:如何結合自身項目更好地做好分層測試設計,並使用各種手段實現分層測試?

關注微信公衆號:騰訊移動品質中心TMQ,獲取更多測試乾貨!

發佈了162 篇原創文章 · 獲贊 103 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章