正式進入Android的單元測試。我們要開始使用Android Studio來開發。新增專案後一樣會看到在Gradle已經加入測試框架JUnit。
測試程式目錄:
app/src/test 這是我們要放單元測試的地方
app/src/AndroidTest 則是放需要Android framework的測試,也就是上一篇提到的Instrumented tests。放在這個目錄的測試只能執行在Android裝置或模擬器。
在寫Android App時,最常寫到的就是Activity了。很容易的你就會把很多的程式都寫在Activity。在Android的寫單元測試要能順利,第一個就是把能不需要寫在Activity的都提出。以下的範例將示範將不需要寫在Activity的提出,為這些邏輯加上測試。
這裡有一個範例是註冊的功能。輸入帳號及密碼後可註冊為會員。
功能描述:
1.帳號至少需6碼,第1碼為英文。
2.密碼至少需8碼,第1碼為英文,並包含1碼數字。
3.點擊「註冊」,若失敗則使用AlertDialg告訴使用者失敗原因。
4.點擊「註冊」,若成功則導至註冊成功頁。
這個範例先不考慮要儲存註冊會員需要呼叫Web API。只是單純的將帳號密碼填好後,做資料檢查,如果符合帳號及密碼的格式,我們就視為成功。
在UI畫面(請直接參考附件程式碼)都好了之後,為「註冊」的按鈕寫事件,在Activity的onCreate加入按鈕send的事件,在點下送出button時,檢核帳號是否符合規則。
send.setOnClickListener {
val loginId = loginId.text.toString()
val pwd = password.text.toString()
var isLoginIdOK = false
//帳號至少6碼,第1碼為英文,
if (loginId.length >= 8) {
if (loginId.toUpperCase().first() in 'A'..'Z') {
isLoginIdOK = true
}
}
...
}
這裡有一段檢核帳號的邏輯:帳號至少需6碼,第1碼為英文。我想要寫一個測試來檢核邏輯是否正確。但像這樣的寫法,你會發現,寫在Activity就會很難測試。
這一段檢核帳號密碼欄位規則的邏輯跟UI沒什麼關係,我們可以把他提出到一個類別來檢核帳號的正確性。
將檢核帳號提出方法到RegisterVerify
的isLoginIdVerify
class RegisterVerify {
fun isLoginIdVerify(loginId: String): Boolean {
var isLoginIdOK = false
//帳號至少6碼,第1碼為英文,j
if (loginId.length >= 6) {
if (loginId.toUpperCase().first() in 'A'..'Z') {
isLoginIdOK = true
}
}
return isLoginIdOK
}
}
原Activity,則將檢核方式改為呼叫RegisterVerify().isLoginVerify(loginId)
var isLoginIdOK = RegisterVerify().isLoginIdVerify(loginId)
將驗證的邏輯提出到RegisterVierify類別後,我們就可以針對它去測試。
在app/src/test裡新增測試
1.新增類別:RegisterVerifyTest
2.新增測試方法:isLoginIdVerify()
class RegisterVerifyTest {
@Test
fun loginVerifyTrue() {
val registerVerify = RegisterVerify()
//驗證帳號為A123456,長度滿6個字,驗證結果應為true
assertTrue(registerVerify.isLoginIdVerify("A123456"))
}
@Test
fun loginVerifyFalse() {
val registerVerify = RegisterVerify()
//驗證帳號為A12345,長度不滿6個,驗證結果應為false
assertFalse(registerVerify.isLoginIdVerify("A1234"))
}
}
點選綠色三角行,執行測試。結果為綠燈,通過測試。這樣就完成了將與Activity無關的邏輯提出一個類別,來達到可測試的目的了。
像這些用來檢核輸入欄位規則的功能,例如密碼規則、Email、手機號碼規則。為這些檢核撰寫測試,CP值就很高。因為通常這些驗證的正確性都很重要的,也容易寫錯的。但寫起測試卻是很簡單,簡單的擷取方法就可以做到。可不要小看擷取方法,很多時候,就樣做就能讓你的重要程式可以被測試到。
把在Activity裡卻跟View無關的程式,可以提出去的都提出去
當然也不是所有跟View無關的程式碼,都可以用擷取方法處理。更進階的方法,我們就留到第三單元架構篇再介紹怎麼讓View更乾淨。
另外,現實生活你可不能像這個範例,把Production code在沒有測試保護的情況,就直接修改。在沒有單元測試的保護下,如果要重構,你可以先建立一個UI測試來保護你現有的程式碼再進行重構。
範例下載:https://github.com/evanchen76/AndroidUnitTestSample
小技巧
擷取方法的快速鍵 Command + Option + M (Ctrl + Alt + M)