Android代碼單元測試

Android代碼單元測試

1. 目的

  • 單元測試是白盒測試,可以驗證具體的功能模塊邏輯是否正確
  • 保證代碼質量,對代碼邏輯進行方法級別的測試,確保每一個功能模塊的邏輯正確
  • 在良好的單測覆蓋率之下,項目可以在保證質量的前提下進行快速迭代

2. 測試用例覆蓋範圍

一個待測試頁面對應多個業務單元,每一個業務單元對應一個測試用例,每一個測試用例都是一條鏈路(好比點擊一個按鈕後產生的一系列直接影響如頁面跳轉等),實現條件覆蓋和路徑覆蓋。
在Android單元測試中,測試用例不須要覆蓋全部的方法邏輯(這也是不太現實的),應該專一於本身編寫的業務邏輯等代碼的測試覆蓋,像 Android SDK 裏的方法回調是不須要測試的。html

3. 怎樣測試邏輯方法

3.1 目標方法有明確的返回值

編寫單元測試時調用這個方法,驗證返回值是否符合預期android

3.2 目標方法自己沒有返回值,可是會改變一些對象的(屬性||狀態)

調用該方法,而後驗證方法改變的對象的(屬性||狀態)是否符合預期git

3.3 目標方法沒有返回值,也不會改變對象

調用該方法,而後驗證其行爲,好比按鈕的點擊事件,驗證是否彈出Toast、是否有彈框、是否有頁面跳轉等瀏覽器

4. 技術選型

  • JUnit斷言
  • Mockitomock數據,數據解耦
  • Robolectric在JVM上運行單測,不須要模擬器or真機
  • Jacoco統計測試覆蓋率,便於補充完善單測

5. GET STARTED

  1. 咱們的單元測試基於Robolectric,由於它直接運行於JVM之上,運行單測時速度更快,不須要準備Android環境,不用使用真機||Android模擬器運行測試。當須要進行依賴解耦時,可使用Mock框架
  2. 單元測試主要是針對邏輯進行測試,因此就須要App項目的架構清晰,可測試性好,將UI和邏輯分開,否則的話,仍是先重構吧
  3. 測試代碼在app/src/test目錄下

5.1 單元測試環境配置(已完成)

  • Robolectric && JUnit:在app/build.gradle中引入
dependencies {
    
    XXXXXX
    
    testCompile 'junit:junit:4.10'
    testCompile 'org.robolectric:robolectric:3.2.2'
    testCompile 'org.robolectric:shadows-multidex:3.2.2'
    
    XXXXXX
}
複製代碼
  • Mock配置:在app/build.gradle中引入
dependencies {

    XXXXXX

    testCompile "org.mockito:mockito-core:1.+"
    
    XXXXXX
}
複製代碼
  • jacoco:在app/build.gradle中引入
apply from: 'http://git.caimi-inc.com/client/jacoco-plugin/raw/master/jacoco-plugin.gradle'
複製代碼
  • 友情提示:在第一次用Robolectric跑單測時,會下載一堆依賴,可能會比較慢

5.2 新建||更新測試用例文檔

  1. 若是是給新頁面編寫單測,須要新建一個單測文檔,放在docs/單元測試下:好比是WacaiLoginActivity頁面的單測,則文檔名爲WacaiLoginActivity用例列表
  2. 根據單測文檔模板編寫對應的測試用例,更新該單測用例文檔

5.3 編寫測試用例代碼

  1. 根據測試用例文檔編寫測試用例代碼
  2. 一個頁面||工具類對應一個測試類,用例文檔中一個測試用例對應一個測試用例方法

5.4 查看單測覆蓋率,以便完善單測

  1. 進入項目所在目錄,執行./gradlew jacocoTestReport
  2. 執行成功以後,會在目錄app/build/reports/jacoco生成詳細的覆蓋率報告,使用瀏覽器打開index.html便可查看
  3. jacoco執行成功以後,同時會將報告上傳到pages上,查看地址:pages.wacai.info/client/andr…
    1. 其中,APP_VERSION表示當前應用的版本號versionCode
  4. 若是執行失敗,則說明有單測跑不過,須要進行檢查,可能緣由:測試用例寫得有問題、被測試的邏輯代碼有問題、測試框架(配置||環境)有問題
    1. 測試用例有問題:修改測試用例,使之符合正確的邏輯
    2. 被測試的邏輯代碼有問題:fix代碼邏輯問題
    3. 測試框架(配置||環境)問題:修改配置or環境
  5. 查看單測覆蓋率,包括分支覆蓋率和行覆蓋率
    1. 分支覆蓋率:條件執行時不一樣的輸入條件致使的不一樣邏輯走向,最多見的是if-else兩個分支,分支覆蓋率是指被測試代碼覆蓋的分支數佔整體分支的比例,體現的是不一樣輸入條件下代碼各類邊界狀況的覆蓋狀況
    2. 行覆蓋率:被測試代碼覆蓋的邏輯代碼行數佔整體邏輯代碼行數的比例,是一個整體的數值,是一個比較絕對的值
  6. 根據jacoco生成的測試報告不斷完善測試用例,直至覆蓋全部的分支、邊界等。jacoco生成的測試報告很是直觀,可以很容易地看出哪些部分的代碼被覆蓋到了,哪些沒有被覆蓋到,很方便咱們完善測試用例

5.5 文檔式單測流程圖

6. 示例:挖財寶-挖財帳號登陸頁單元測試實踐

爲了介紹單元測試的實施過程,下面以挖財寶挖財帳號登陸頁做爲單元測試實踐案例。該案例的開發和測試涉及到了TextView, EditText, Button, Checkbox, ImageView,包含了各類點擊、頁面跳轉等邏輯。頁面以下圖所示bash

對頁面進行單元測試的時候,咱們首先須要分析頁面,針對頁面提取出業務邏輯,提取出的業務邏輯如上圖所示。根據這些邏輯來設計單元測試的case(帶有Test註解的被測試方法),業務邏輯包括需求中的業務以及其餘的須要維護的代碼邏輯。爲了減小單元測試case的維護成本,業務流程不容許跨頁面,以頁面爲基本單位。架構

挖財帳號登陸頁的單元測試case設計以下:app

目標頁面 業務覆蓋 界面元素 邏輯描述 最小斷言數 case名稱
挖財帳號登陸頁 WacaiLoginActivity 點擊左上角返回 1. 左上角TextView控件 1. 點擊左上角TextView控件,關閉結束登陸頁 1 testGoBack
輸入帳號、密碼 1. 帳號輸入框(手機/郵箱/帳號)
2. 帳號輸入框右側清空圖標ImageView
3. 密碼輸入框EditText
4. 密碼輸入框右側隱藏密碼圖標ImageView
1. 向帳號輸入框輸入內容
2. 向密碼輸入框輸入內容
3. 當帳號輸入框沒有內容時,帳號輸入框右側清空圖標ImageView隱藏
4. 當帳號輸入框有內容時,帳號輸入框右側清空圖標ImageView顯示
5. 當密碼輸入框沒有內容時,隱藏密碼圖標隱藏
6. 當密碼輸入框有內容時,隱藏密碼圖標顯示
7. 點擊清空圖標,帳號輸入框文本清空
8. 點擊隱藏密碼圖標,密碼輸入框文本清空
6 testInputAccountAndPassword
點擊登陸 1. 登陸按鈕
2. 帳號輸入框
3. 密碼輸入框
1. 點擊登陸按鈕
2. 帳號密碼輸入框爲空,則彈出Toast,頁面不跳轉
3. 帳號不爲空,密碼爲空,彈出Toast,頁面不跳轉
4. 帳號密碼均不爲空,正常登陸邏輯
4 testLogin
自動填充上次登陸用戶的用戶名 1. 帳號輸入框 2. 密碼輸入框 當用戶曾經登陸過期,進入頁面會自動在帳號輸入框填充上一次登陸成功用戶的用戶名:
1. 填充帳號輸入框
2. 填充以後,密碼輸入框得到焦點
2 testPastePreAccount
直接點擊跳轉 1. 右上角註冊TextView控件
2. 忘記密碼TextView控件
3. 挖財平臺註冊協議TextView控件
4. 挖財隱私權政策TextView控件
1. 點擊註冊跳轉到手機號註冊登陸頁面
2. 點擊忘記密碼跳轉到找回密碼頁面
3. 點擊挖財平臺註冊協議或者挖財隱私權政策,跳轉到對應的WebView
4 testJumpDirectly
點擊切換是否贊成挖財註冊協議 1. 贊成挖財註冊協議Checkbox勾選框
2. 登陸按鈕
1. 勾選贊成挖財註冊協議,則登陸按鈕可點擊;不然不可點擊
2. 進入頁面時默認勾選贊成挖財註冊協議
3 testAgreeRegisterProtocol

接下來須要在單元測試的工程中實現上述case。最小斷言數是從業務邏輯考慮的一個數值,並非代碼的邊界條件,真實的case須要考慮代碼的各類邊界狀況,好比空指針等,所以,通常實際斷言數會大於最小斷言數。實際斷言數=最小斷言數(業務需求斷言)+技術需求斷言。框架

寫完case以後須要跑一遍單測獲得單測報告,根據單測報告不斷完善單測,提升單測覆蓋率。ide

7. 其餘問題

  • Robolectric 3.+在各個場景下如何編寫測試用例,請查看這裏
  • 使用Robolectric 3.+遇到的常見問題彙總,請查看這裏

8. 總結

  • 單元測試不是一個可以產生直觀可見效益的工程,可是對於保障快速迭代時的代碼質量具備重要意義。試想一下,面對一個單元測試覆蓋率很高的工程,若是你要進行部分重構的話也會更有信心吧?你每一點對代碼的改動,都有可能對其餘部分的業務邏輯產生影響,有了單元測試,代碼對邏輯的影響能夠經過運行單測來斷定,若是單測覆蓋完備&&單測運行經過,那麼就能夠認爲改動對現有業務邏輯沒有影響
  • 項目架構很影響單元測試的實施,井井有條、代碼解耦、可測試性好的代碼在編寫單測的時候是很是舒暢的。若是項目中UI和邏輯高度耦合,代碼邏輯都堆在Activity中,那麼,你最須要的可能不是單測,而是對項目的重構,各個模塊進行解耦、UI和邏輯解耦等
  • 編寫代碼的時候須要適當考慮代碼的可測試性

9. 最後

以上就是文檔式單測的內容,目前正在實踐之工具

10. 參考資料

相關文章
相關標籤/搜索