《Android編程權(quán)威指南》第 20 章第二篇蚌讼,補(bǔ)充完 BeatBox 應(yīng)用的單元測試?yán)病?/p>
第一篇地址:
https://juejin.cn/post/7033347707473231879
八城瞎、編寫測試函數(shù)
測試函數(shù)將用到 @Test 注解谜疤。
@Test
fun exposesSoundNameAsTitle(){
assertThat(subject.title,`is`(sound.name))
}
assertThat(...) 選 org.junit 庫里的 Assert.assertThat(...) 函數(shù)商模,is(...) 選 org.hamcrest 庫里的 Is.is 函數(shù)苏携。
上面代碼意思是斷定測試對象獲取標(biāo)題函數(shù)和 sound 的獲取文件名函數(shù)返回相同的值鉴分。如果不同楣责,單元測試失敗。
接下來測試 SoundViewModel 和 BeatBox.play(Sound) 的交互坯台。
@Test
fun callsBeatBoxPlayOnButtonClicked(){
subject.onButtonClicked()
}
為了測試 SoundViewModel 不讓它跟 BeatBox 綁太死炬丸,不依賴 BeatBox 對象,就在此測試案例中模擬出 BeatBox 對象蜒蕾。
class SoundViewModelTest {
...
private lateinit var beatBox: BeatBox
@Before
fun setUp() {
beatBox = mock(BeatBox::class.java)
...
}
...
}
Mockito 的 verify(Object) 可以確認(rèn)稠炬,要測試的函數(shù)是否都按預(yù)期被調(diào)用了。
@Test
fun callsBeatBoxPlayOnButtonClicked(){
...
verify(beatBox).play(sound)
}
然后按照書中過程補(bǔ)充修正一下咪啡,把 BeatBox 傳給 SoundViewModel首启,修正 SoundHolder 中的錯誤,在測試類里提供模擬板 BeatBox撤摸,實(shí)現(xiàn) onButtonClicked() 函數(shù)毅桃。具體代碼略了,見 Demo准夷。
九钥飞、數(shù)據(jù)綁定回調(diào)
在布局文件里,添加數(shù)據(jù)綁定 lambda 表達(dá)式衫嵌,讓按鈕對象和 SoundViewModel.onButtonClicked() 函數(shù)關(guān)聯(lián)起來读宙。
<Button
android:layout_width="match_parent"
android:layout_height="120dp"
android:onClick="@{()->viewModel.onButtonClicked()}"
android:text="@{viewModel.title}"
tools:text="Sound name" />
運(yùn)行應(yīng)用,點(diǎn)擊按鈕楔绞,就能聽到奇怪的喊叫聲了结闸,可以自行體驗(yàn)下。
十酒朵、釋放音頻
音頻播放完畢桦锄,應(yīng)調(diào)用 SoundPool.release() 函數(shù)釋放 SoundPool。
在 BeatBox 中添加方法:
fun release(){
soundPool.release()
}
然后在 MainActivity 銷毀的時候調(diào)用它:
override fun onDestroy() {
super.onDestroy()
beatBox.release()
}
十一蔫耽、深入學(xué)習(xí):整合測試
單元測試中结耀,受測對象是單個類。保證各個類單元正確運(yùn)行针肥,相互之間的交互符合預(yù)期饼记。
整合測試中,受測對象是應(yīng)用的一部分慰枕,包括協(xié)同工作的眾多對象具则。驗(yàn)證受測各部分已正確整合在一起,按預(yù)期發(fā)揮作用具帮。在 Android 平臺上博肋,整合測試通常還是指 UI 級別的測試(和UI部件交互低斋,驗(yàn)證它們的行為表現(xiàn)是否符合預(yù)期)。常以 instrumentation 測試來實(shí)施匪凡。
Espresso 是 Google 開發(fā)的一個 UI 測試框架膊畴,可用來測試 Android 應(yīng)用。通常新項(xiàng)目都會自動的引用這個依賴病游。
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
可用它來測試某個 activity 的行為唇跨。
斷定屏幕上某個視圖顯示了第一個 sample_sounds 受測文件的文件名:
@RunWith(AndroidJUnit4::class)
class MainActivityTest {
@get:Rule
val activityRule = ActivityTestRule(MainActivity::class.java)
@Test
fun showsFirstFileName(){
onView(withText("65_cjipie"))
.check(matches(isDisplayed()))
}
}
@RunWith(AndroidJUnit4.class) 表明,這是一個Android工具測試衬衬,需要 activity 和其他 Android 運(yùn)行時環(huán)境支持买猖。
activityRule 上的 @get:Rule 注解告訴 JUnit,運(yùn)行測試前滋尉,要啟動一個 MainActivity 實(shí)例玉控。
onView(withText("65_cjipie")) 會找到顯示 “65_cjipie” 的視圖,對其執(zhí)行測試狮惜。
check(matches(isDisplayed())) 用來判定視圖在屏幕上看得見高诺。
有關(guān) Espresso 詳情參考:
https://developer.android.com/training/testing/espresso
十二、深入學(xué)習(xí):模擬對象與測試
模擬對象假扮成其他不相干的組件碾篡,為的就是隔離受測對象虱而。對于單元測試來說,能快速創(chuàng)建模擬對象的 Mockito 非常有用开泽。
但是整合測試時薛窥,最好避免使用像 Mockito 這樣的自動模擬測試框架,因?yàn)槟M太重了眼姐,需要很多整合測試共享,太繁瑣佩番。
基本原則:模擬對象的效用不應(yīng)超出受測組件的邊界众旗。應(yīng)著重關(guān)注測試范圍,防止測試越界趟畏。
十三贡歧、挑戰(zhàn)練習(xí):播放進(jìn)度控制
給 BeatBox 應(yīng)用添加播放進(jìn)度控制功能,在MainActivity中赋秀,使用SeekBar部件控制SoundPool的play(Int, Float, Float, Int, Int, Float)函數(shù)的播放速率參數(shù)值利朵。
參考 Demo,指不定啥時候就更新了猎莲。O(∩_∩)O哈哈~
十四绍弟、挑戰(zhàn)練習(xí):設(shè)備旋轉(zhuǎn)問題
給 BeatBox 應(yīng)用添加一個 Jetpack 版 ViewModel,實(shí)現(xiàn)在設(shè)備旋轉(zhuǎn)時保存BeatBox對象著洼。
參考 Demo樟遣,指不定啥時候就更新了而叼。O(∩_∩)O哈哈~
其他
BeatBox 項(xiàng)目 Demo 地址:
https://github.com/visiongem/AndroidGuideApp/tree/master/BeatBox