專治時間長 —5分鐘測試Android覆蓋安裝
一、痛點
覆蓋安裝測試,作為一項基本的測試類型是不可或缺的。它存在的主要價值:驗證老版本覆蓋升級到新版本,用戶和系統數據能夠正確遷移,以及保障用戶升級后的功能可用性。
但是說他痛在什么地方呢?
需要測試的版本多
每個版本需要覆蓋的用例多
二、解決方案
2.1 思路
從哲學上說,任何事物都是發展變化的。我們需要在“變化”中找尋“不變”的本質和規律。在覆蓋安裝過程中,我們也要找到“不變”的部分,那就是我們能夠“減少工作量”的地方。
例如:某APP1.0版本覆蓋升級到APP2.0版本。
在這個過程中哪些是不變的部分呢?
- 程序代碼
了解Android覆蓋安裝的同學都知道,覆蓋安裝后,APP1.0版本的程序代碼,完全更新為APP2.0版本的程序代碼。但是,這種變化會在“迭代”測試中完全保證。因為“迭代”測試中“全新安裝”APP2.0程序代碼和“覆蓋安裝APP2.0程序代碼”是相同的。
- 用戶數據
用戶數據—用戶使用APP過程中產生的數據。例如:用戶使用“瀏覽器”打開了www.qq.com, 那么瀏覽器訪問歷史中的www.qq.com就是用戶數據。很顯然,用戶數據在覆蓋升級的過程中不應該被改變。不僅如此,升級后的用戶數據必須能夠正常訪問使用。這樣才能保證用戶在APP覆蓋升級后使用的連貫與一致性。當然,這是理想的情況,在覆蓋升級過程中用戶數據也有可能發生變化。
很顯然,(1)如果“用戶數據(不變部分)”,能夠保證在覆蓋升級后正常訪問使用,這部分測試工作量就能被釋放。(2)針對“用戶數據(變化部分)”,測試人員需要人工介入確認是否是問題。
現在的主要問題就變成了:如何保證“用戶數據(不變部分)”的功能正確性?
【論據1】APP1.0覆蓋升級為APP2.0后程序代碼=全新安裝APP2.0的程序代碼。(成立)
【論據2】APP2.0在全新安裝狀態下,“迭代測試”需要對主要功能進行“地毯式”的功能測試。只要使用“用戶數據(不變部分)”作為測試數據,功能正確性就已經得到了保證。而在很多測試組,也確實就是這樣做的。(成立)
【結論】“用戶數據(不變部分)”在覆蓋升級后,不需要測試。(成立)
有了這個結論,我們就能把主要精力放在區分“用戶數據”的變化和不變部分。要找到用戶數據變化,那就需要進行對比。例如:覆蓋升級前用戶數據是[1、2、3],覆蓋升級后用戶數據變為[1、2、5、6],那么變化的用戶數據就是[5、6]。下面將要介紹三個測試維度對比。
2.2 三個測試維度
在上節思路指導下,我們采用了如下三個維度的對比用戶數據。 我們還是以某APP1.0覆蓋升級到APP2.0為例子。
用戶數據A/B/C中都分別包含了:
-
Sqlite數據庫文件
-
Shared preference配置XML文件
-
文本和二進制文件
那么通過對用戶數據A/B/C進行不同的對比,可以得到不同的結論。從覆蓋類型上看,我們可以分為Struct、Data、Scale三個維度類型。
2.2.1 Struct對比(校驗升級代碼)
Struct對比數據B(1.0升級到2.0版本后data目錄)和C(全新安裝2.0后data目錄),來驗證“驗證升級代碼邏輯”正確性。正常情況下,B和C中所有sqlite數據表結構、配置XML文件結構、文本和二進制文件應該保持一致。如果不一致,就證明在1.0升級到2.0的升級代碼中有bug, 使得1.0升級到2.0后結構,無法和2.0全新安裝保持一致。這種不一致可能存在三種情況:
- 結構新增
例如:B中的switch表
C中的switch表
很明顯是1.0升級到2.0的時候,對switch表升級代碼漏掉了增加一列phone的操作。但是在2.0全新安裝的時候, 在switch表確增加了phone字段。這就是我們要尋找的Bug。關于這里的數據表中的值, 都是應用啟動后默認的值。
- 結構修改
例如:B中的switch表數據類型
C中的switch表數據類型
很明顯是1.0升級到2.0的時候,對switch表升級代碼漏掉了更改name字段類型的操作。但是在2.0全新安裝的時候, 在switch表確name字段修改為了Text類型。這也是我們要尋找的Bug。
- 結構刪除
例如:B中的switch表
C中的switch表
很明顯是1.0升級到2.0的時候,對switch表升級代碼漏掉了刪除列name的操作。但是在2.0全新安裝的時候, 在switch表確沒有name字段。這種刪除表的情況比較少,一般來說都是增加和修改。
2.2.2 Data類型(數據內容對比)
Data數據對比A(1.0全新安裝并且插入數據后data目錄)和B(1.0全新安裝并且插入數據后升級到2.0版本后data目錄),來驗證“升級過程中數據變化”。這里的“插入數據”是指應用啟動后插入樣本數據。例如:瀏覽器的訪問Bookmark表中制造一些樣本數據,方便檢驗數據遷移的過程。
制造樣本數據主要有兩種方法:
- 數據導出法
通過手工操作應用,先制造樣本數據。例如上例中,手動打開瀏覽器點擊“新浪網”。然后通過sqlite工具導出訪問歷史表中的數據保存。在下一次測試的時候, 在進行導入。
- API調用法
通過應用預留的API接口,可以直接進行數據插入。當然,這個和具體應用的可測性結構有關。
- 自動化腳本法
通過GUI自動化腳本,在應用界面模擬人工操作制造數據,也是一種不錯的方法。
當數據A和B對比完全一致
我們基本可以認為數據遷移是正確的。為什么呢?因為如果A和B數據完全一致,那么在從1.0覆蓋升級到2.0數據也應該是可用的。但是,如果出現2.0使用數據失敗,那么這種問題在2.0版本的“迭代”測試中可以發現,而不屬于“覆蓋安裝”的范疇。所以可以認為只要A和B數據完全一致,數據遷移就是正確的。
在數據A和B對比不一致
這種不一致并不能完全認為是錯誤的,這個需要測試人員同開發人員共同確認是否是Bug。分為三種情況:
- 數據修改
這是我們首先要搞清楚的問題,如何判定是數據修改,而不是數據刪除和新增呢?例如:
A中的Bookmark表
B中的Bookmark表
從數據庫數據分析角度,可以認為id=1,id=2,id=3的數據被刪除,然后從新插入了id=4,id=5,id=6的數據。這種情況從業務上看,顯然url字段保持不變,id發生了變化,我們可以認為是修改。最后,我們采納了這是修改的建議。因為,這樣更符合業務情況,使測試人員對結果的判斷上更加簡單。
但是,修改的判斷規則是如何定的呢?我們來看一下Bookmark表中的結構。
一般來說,Unique Constraint約束的字段在表中都是聯合主鍵。所以我們判斷修改的算法是:
“主鍵”或者“聯合主鍵”其中二者滿足其一,就認為是修改的數據。
- 數據新增
有了判斷數據修改的規則, 數據新增判斷就很簡單了。
- 數據刪除
有了判斷數據修改的規則, 數據刪除判斷就很簡單了。
2.2.3 Scale類型(測試關注點對比)
Scale類型對比A(全新安裝1.0版本data目錄)和C(全新安裝2.0版本data目錄),目的“從數據層面觀察兩個版本差異, 給系統測試人員以指導”。例如:1.0版本沒有bookmark表,但是2.0版本中出現了bookmark表,就證明2.0新增了bookmark相關功能,需要提醒測試人員注意。
那么以上三個維度測試是如何實現的呢?請繼續往下看。
2.3 自動化實現
體驗地址: http://10.20.73.81:8080/OverrideTest/testAction!login
體驗用戶:ciro
體驗密碼:123
Note: 要創建測試任務,請注冊自己的專用帳號。
步驟說明:
1.用戶輸入APP的“最近N個歷史版本APK包”和“最新版本APK包”。例如:N=2
歷史包:1.0、2.0
最新包:3.0
循環2次:
第一次:1.0->3.0
第二次:2.0->3.0
2.系統將用戶上傳的APK包下發到測試手機。
3.雖然可以一次上傳多個“歷史版本APK包”,但是系統中一個任務只包含:一個“歷史版本APK包”和一個“目標版本APK包”。很顯然,N個歷史版本就會建立N個測試任務。在測試手機上“全新安裝”一個任務的歷史版本APK包。
4.啟動APP。
5.如果有樣本數據的自動化腳本,這里將會進行樣本數據插入。
6.拉取APP的Data目錄下所有內容A。
7.不卸載“歷史版本APK”, 直接覆蓋安裝后的“最新版本APK”。
8.啟動覆蓋安裝后的APP。
9.APP啟動后,需要激活升級邏輯(參考:升級邏輯觸發)。
10.拉取APP的Data目錄下所有內容B。
11.將用戶上傳的APK包下發到手機。
12.卸載已經安裝的APP,然后全新安裝“最新版本APK”。
13.啟動全新安裝“最新版本APK”。
14.拉取APP的Data目錄下所有內容C。
15.將Data目錄A和B輸入文件對比模塊進行對比(參考:Data類型對比)。
16.將Data目錄C和B輸入文件對比模塊進行對比(參考:Struct類型對比)。
17.將Data目錄A和C輸入文件對比模塊進行對比(參考:Scale類型對比)。
18.文件對比模塊,將輸入的sqlite文件、xml文件、文本文件和二進制文件進行對比。
19.保存對比的結果到DB。
20.用戶收到測試報告。
三、項目實戰
3.1 經典實例
應用寶
歷史版本:4.1、4.1.1、4.2、4.4、4.5、4.6、5.0、5.1
最新版本:5.2
測試類型:struct對比(驗證升級代碼)
發現問題:
“全新安裝5.2版本”和“任意1個歷史版本升級到最新5.2版本”對比,數據庫新增了一張表switch_phone_table。也就是說,升級邏輯代碼漏掉了生成switch_phone_table表代碼。
經過和測試人員溝通,發現這個表是應用寶“換機助手”的數據表。由于缺少了switch_phone_table,“面對面換機”在完成資料發送后,不會出現“換機報告”幾個字,也無法點擊。
最后測試人員確認是覆蓋安裝Bug。這個Bug其實隱藏的很深,普通測試路徑不容易覆蓋到,但通過數據層來看,就很容發現。
騰訊地圖
歷史版本:3.1、4.0、4.1、4.7、4.8
最新版本:4.9
測試類型:struct對比(驗證升級代碼)
發現問題:
騰訊地圖 從4.0 升級到 4.9版本, 數據庫中少生成一張favorite.db/FavoriteStreetEntity表。 這會導致 在4.9版本中收藏“街景”后, 數據無法寫入數據庫。如果重新啟動騰訊地圖, 剛才收藏的“街景”就會消失掉。
如果歷史版本多,覆蓋安裝工作量大,人工測試就容易遺漏這樣的測試路徑。通過自動化觀察數據層的遷移,就很容易發現問題,提高覆蓋安裝測試效率。
3.2 收益統計
本方案的主要收益,源于減少覆蓋安裝的測試關注點,縮短測試時間。通過在手機QQ瀏覽器項目實踐,我們得到如下數據:
- 成本
自動化建設時間:4周=160小時*人
樣本數據采集時間:6(版本)x0.5(小時/版本)=3小時\人
固定成本共計: 163小時*人
由于自動化建設屬于固定投入, 這部分收益通過長期多版本測試攤薄,可以忽略不計.樣本數據采集時間是個主要耗時, 平均每個版本需要0.5小時*人. 一旦歷史版本準備過一次樣本數據,以后就不用再準備了,所以這部分耗時長期攤薄,也可以忽略。
- 收益
自動化以后,平均每個版本覆蓋安裝測試關注點數量減少50%。關注點的減少也直接導致測試時間的降低。
手機QQ瀏覽器項目組每次發布,關注最近6個版本的覆蓋安裝情況。從上圖統計可以看出,通過自動化以后“上線前覆蓋安裝測試時間”縮短60%,“集成覆蓋安裝測試時間”縮短60%。
其他騰訊產品試用后,得到以下數據:
通過數據表明經過本方案過濾后,覆蓋安裝測試驗證點減少50%左右。
四、總結思考
4.1 樣本數據插入
從項目結果中, 我們可以發現通過Data類型(數據內容對比),讓我們更有可能發現問題。但是,這需要提前插入樣本數據。有這樣一些方法:
- 手工導出和自動化導入用戶數據
針對每個歷史版本:測試人員通過手工操作構造用戶數據。這個可以在迭代測試中就完成,不占用額外時間。
優點:操作簡單;運行時間短。
缺點:手工操作耗時長;每個歷史版本需要一份樣本數據。
我們就采取的這種方案。
- 界面自動化腳本創建用戶數據
通過界面自動化,模擬用戶操作創建用戶數據。
優點:模擬用戶操作,構造數據更準確。
缺點:界面自動化運行時間較長;每個版本需要維護一個自動化腳本(版本之間存在界面差別)。
- 界面控件遍歷操作創建用戶數據
這是一種GUI自動化的隨機遍歷操作。類似于monkey測試,但是點擊是以界面控件為單位。參考:http://km.oa.com/group/18017/articles/show/150352?kmref=search
優點:不用寫任何腳本和輸入數據。
缺點:隨機遍歷創建用戶數據可能存在不全面;界面控件隨機操作運行時間較長。
4.2 升級邏輯激活
通過我們在多個項目實踐,我們發現APP的升級邏輯觸發時間點:
- APP啟動時觸發
這種情況比較便于自動化處理,直接啟動APP即可。
- APP啟動后某功能激活時觸發
部分模塊升級邏輯要推遲到模塊啟動才能觸發,這就要求我們要有一套模塊觸發機制。這部分工作可以通過UI自動化工具完成,本項目中采用QQDriver自動化腳本完成。
4.3 與精準測試結合
理論上說,如果覆蓋安裝函數入口規范, 調用地點集中。例如:所有升級操作都在這樣的函數中。
通過代碼梳理,能夠找到應用覆蓋安裝的函數入口。通過對比“當前版本”和“歷史版本”覆蓋安裝函數代碼差異,覆蓋安裝邏輯變化的功能模塊,進行覆蓋安裝測試。從而縮短覆蓋安裝測試的時間。
但是經過手機QQ瀏覽器項目實際操作發現,覆蓋安裝代碼都位置分散,而且函數寫法不規范。跨大版本的svn代碼對比,發現幾乎所有功能模塊的覆蓋安裝邏輯都有改動。這樣就無法縮小測試范圍,達到精準測試的目的。所以如果要實現精準化覆蓋安裝測試,覆蓋安裝函數入口函寫法規范和調用地點統一是前提,這個可以給項目組提可測性需求實現。
來自:http://tmq.qq.com/2016/07/specialist-in-a-long-time-5-minutes-test-android-cover-installation/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
來自:http://blog.csdn.net/tmq1225/article/details/52126314