1. 事前準備
在先前的程式碼研究室中,您已學到如何建立及執行單元測試,本程式碼研究室著重於檢測設備測試。您有機會瞭解檢測設備測試的樣貌及撰寫方式。
必要條件
- 您已在 Android Studio 中建立專案。
- 您具備在 Android Studio 中編寫程式碼的經驗。
- 您對於在 Android Studio 中導覽專案有一些經驗。
- 您在 Android Studio 中撰寫了簡單的單元測試。
課程內容
- 檢測設備測試的樣貌。
- 如何執行檢測設備測試。
- 如何撰寫檢測設備測試。
需求條件
- 已安裝 Android Studio 的電腦。
- Tip Time 應用程式的解決方案程式碼。
下載本程式碼研究室的範例程式碼
在本程式碼研究室中,您將使用先前解決方案程式碼的 Tip Time 應用程式進行檢測設備測試。
- 前往專案指定的 GitHub 存放區頁面。
- 驗證分支版本名稱與程式碼研究室中指定的分支版本名稱相符。例如,在下列螢幕截圖中,分支版本名稱為「main」。
- 在專案的 GitHub 頁面中,按一下「Code」按鈕,畫面上會出現彈出式視窗。
- 在彈出式視窗中,按一下「Download ZIP」按鈕,將專案儲存至電腦。等待下載作業完成。
- 在電腦中找到該檔案 (可能位於「下載」資料夾中)。
- 按兩下解壓縮 ZIP 檔案。這項操作會建立含有專案檔案的新資料夾。
在 Android Studio 中開啟專案
- 啟動 Android Studio。
- 在「Welcome to Android Studio」視窗中,按一下「Open」。
注意:如果 Android Studio 已開啟,請改為依序選取「File」>「Open」選單選項。
- 在檔案瀏覽器中,前往已解壓縮的專案資料夾所在的位置 (可能位於「Downloads」資料夾中)。
- 按兩下該專案資料夾。
- 等待 Android Studio 開啟專案。
- 按一下「Run」按鈕 即可建構並執行應用程式,請確認應用程式的建構符合預期。
2. 入門應用程式總覽
Tip Time 應用程式有一個畫面,會顯示供使用者輸入帳單金額的文字輸入方塊、選取小費百分比的圓形按鈕,以及計算小費的按鈕。
3. 建立檢測設備測試目錄
本程式碼研究室的範例程式碼可以正常運作,但缺少測試和測試目錄。我們必須先新增目錄,之後再撰寫任何類型的測試,才能進行檢測設備測試。下載範例程式碼後,請按照下列步驟新增檢測設備測試的類別。
- 最簡單的做法是先從「Android」檢視畫面切換至「Project」檢視畫面。在左上方的專案窗格中,按一下「Android」下拉式選單,然後選取「Project」(專案)。
- 您的專案檢視畫面應如下所示:
- 按一下第一個下拉式選單,然後依序點選「app」->「src」。
- 用滑鼠右鍵按一下「src」,然後選取「New」->「Directory」。
- 畫面上應該會顯示此視窗:
- 選取「androidTest/java」。
- 您現在會在專案結構中看到「androidTest」目錄。
- 用滑鼠右鍵按一下「java」目錄,然後依序選取「New」->「Package」。
- 畫面上會產生以下視窗:
- 在視窗中輸入下列文字,然後按下 Return 鍵:
com.example.tiptime
- 專案視窗應如下所示:
- 最後,用滑鼠右鍵按一下「com.example.tiptime」,然後依序選取「New」->「Kotlin Class/File」。
- 在出現的視窗中輸入
CalculatorTests
,然後從下拉式選單中選取「Class」,並按下 Return 鍵。
4. 撰寫第一個檢測設備測試
現在請撰寫檢測設備測試。請按照下列步驟測試 20% 小費的功能。
- 開啟您剛剛建立的檔案,該程式碼會看起來像這樣:
package com.example.tiptime
class CalculatorTests {
}
- 檢測設備測試需要用到 InstrumentationTestRunner,才能在裝置或模擬器上執行測試。有其他數個檢測執行工具,但在這個測試中,我們將使用
AndroidJUnit4
測試執行工具。如要指定測試執行工具,我們必須使用以下項目為類別加上註解:
@RunWith(AndroidJUnit4::class)
class CalculatorTests {
}
以防萬一,您需要的以下匯入作業:
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.runner.RunWith
現在已完成所有設定,可以開始撰寫測試邏輯。
- Tip Time 應用程式是由單一活動
MainActivity
組成。若要與活動互動,您必須先啟動測試案例。在CalculatorTests
類別中加入以下內容。
@get:Rule()
val activity = ActivityScenarioRule(MainActivity::class.java)
ActivityScenarioRule
來自 AndroidX 測試程式庫。並指示裝置啟動開發人員指定的活動。您需要使用 @get:Rule
加上註解,指定應在各項測試之前於類別中執行後續規則。在本例中,該規則為啟動活動。測試規則是測試所需的基本工具,最終,您也會學到如何自行撰寫。
- 接下來,您需要撰寫測試邏輯本身。建立函式並呼叫
calculate_20_percent_tip()
,並透過@Test
註解加上註解。
@Test
fun calculate_20_percent_tip() {
}
Espresso
本課程主要使用 Espresso 進行檢測設備測試。Espresso 是一種程式庫,可供您在用 Android Studio 建立 Android 專案時立即使用,並可讓您透過程式碼與 UI 元件互動。
此刻,您可能已注意到 Android Studio 提供許多自動完成功能。使用 Espresso 的一大挑戰,就是如果尚未匯入程式庫,系統便無法自動完成方法。所以,如果您未研究說明文件,您會很難在 Espresso 中瀏覽可用方法。在這些課程中,我們將提供完成測試所需的方法。
首先,您必須撰寫程式碼,才能在「Cost of Service」輸入文字檢視區塊中輸入帳單金額。依序前往「app」->「src」->「main」->「res」->「layout」->「activity_main.xml」,指示 TextInputEditText
的 ID 為 cost_of_service_edit_text
。複製 ID 名稱,稍後將用於測試。
實作測試函式
您現在可以在測試類別的 calculate_20_percent_tip()
函式中撰寫測試邏輯。
- 首先,請使用
onView()
函式尋找可互動的使用者介面元件 (在此案例中為TextInputEditText
)。onView()
函式採用ViewMatcher
物件參數。ViewMatcher
基本上是符合特定條件的 UI 元件,在此例中則是具有R.id.cost_of_service_edit_text
ID 的元件。
函式 withId()
會傳回 ViewMatcher
,這是 ID 傳遞至其的使用者介面元件。onView()
會傳回 ViewInteraction
,我們可以與該物件互動,就像在操控裝置一樣。若要輸入文字,請在 ViewInteraction
上呼叫 perform()
。然後,perform()
會採用 ViewAction
物件。有許多方法會傳回 ViewAction
,但現在我們正在使用 typeText()
方法。在 activity_main.xml
中,可以看到預設的小費選項為 20%,因此目前您不必指定要選取的小費選項。
onView(withId(R.id.cost_of_service_edit_text))
.perform(typeText("50.00"))
之後,整個指示會如下所示:
onView(withId(R.id.cost_of_service_edit_text))
.perform(typeText("50.00"))
.perform(ViewActions.closeSoftKeyboard())
- 現在請輸入文字,並按一下「Calculate」(計算) 按鈕進行測試。此程式碼的格式類似於我們用來輸入文字的格式。使用者介面元件並不相同,因此傳遞至
withId()
函式的 ID 名稱會不同。但在方法中的唯一差別是,ViewAction
不同;會以click()
函式取代typeText()
。
onView(withId(R.id.calculate_button))
.perform(click())
- 最後,您必須宣告顯示正確的小費。我們預計小費為 $10.00。在這項測試中,請確認 ID 為
tip_result
的TextView
包含字串形式的預期小費值。
onView(withId(R.id.tip_result))
.check(matches(withText(containsString("$10.00"))))
當系統顯示提示時,請選取下列匯入:
import androidx.test.espresso.assertion.ViewAssertions.matches
import org.hamcrest.Matchers.containsString
在本例中,您使用名為 check()
的不同互動,採用 ViewAssertion
。您可以將 ViewAssertion
視為 UI 元件使用的特殊 Espresso 斷言。斷言是指 TextView
的內容與包含 "$10.00"
字串的文字相符。
執行測試前,請確認匯入內容和程式碼正確無誤,看起來應如下所示 (匯入順序不同並無影響):
package com.example.tiptime
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.hamcrest.Matchers.containsString
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class CalculatorTests {
@get:Rule()
val activity = ActivityScenarioRule(MainActivity::class.java)
@Test
fun calculate_20_percent_tip() {
onView(withId(R.id.cost_of_service_edit_text))
.perform(typeText("50.00"))
onView(withId(R.id.calculate_button)).perform(click())
onView(withId(R.id.tip_result))
.check(matches(withText(containsString("$10.00"))))
}
}
如果您正在使用模擬器,請務必同時查看模擬器和 Android Studio 的視窗。請以執行單元測試的相同做法執行單元測試,也就是用滑鼠右鍵按一下函式左邊的紅色/綠色箭頭按鈕,然後選取第一個選項。看看會發生什麼事吧!
您會發現測試的執行方式就像使用者正在操作應用程式一樣!
5. 擴大測試套件
恭喜!您完成了首次檢測設備測試!
如果您想接受挑戰,可以新增測試其他小費百分比的函式來擴充測試套件。請使用與上方所寫函式相同的格式,唯一需要變更之處,就是撰寫用來選取不同百分比選項的程式碼,並變更傳遞至 containsString()
的值,考量不同的預期結果。別忘了,也可以有向上四捨五入的選項。您可以依 ID 尋找元件並且點擊該元件,藉此切換向上四捨五入切換按鈕,如 onView(withId())
所示範。
6. 解決方案程式碼
7. 摘要
- Android Studio 會在建立專案時產生必要的測試類別。不過,如果您的專案沒有這些類別,您可以手動建立。
- 測試規則會在每次在測試類別中進行測試之前執行。
- Espresso 是檢測設備測試的基本元件,使得使用程式碼就能與使用者介面元件互動。
這門課程很長,給自己鼓掌,做得好!