《Android编程权威指南》第 20 章第二篇,补充完 BeatBox 应用的单元测试啦。
八、编写测试函数
测试函数将用到 @Test 注解。
@Test
fun exposesSoundNameAsTitle(){
assertThat(subject.title,`is`(sound.name))
}
assertThat(…) 选 org.junit 库里的 Assert.assertThat(…) 函数,is(…) 选 org.hamcrest 库里的 Is.is 函数。
上面代码意思是断定测试对象获取标题函数和 sound 的获取文件名函数返回相同的值。如果不同,单元测试失败。
接下来测试 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) 可以确认,要测试的函数是否都按预期被调用了。
@Test
fun callsBeatBoxPlayOnButtonClicked(){
...
verify(beatBox).play(sound)
}
然后按照书中过程补充修正一下,把 BeatBox 传给 SoundViewModel,修正 SoundHolder 中的错误,在测试类里提供模拟板 BeatBox,实现 onButtonClicked() 函数。具体代码略了,见 Demo。
九、数据绑定回调
在布局文件里,添加数据绑定 lambda 表达式,让按钮对象和 SoundViewModel.onButtonClicked() 函数关联起来。
<Button
android:layout_width="match_parent"
android:layout_height="120dp"
android:onClick="@{()->viewModel.onButtonClicked()}"
android:text="@{viewModel.title}"
tools:text="Sound name" />
运行应用,点击按钮,就能听到奇怪的喊叫声了,可以自行体验下。
十、释放音频
音频播放完毕,应调用 SoundPool.release() 函数释放 SoundPool。
在 BeatBox 中添加方法:
fun release(){
soundPool.release()
}
然后在 MainActivity 销毁的时候调用它:
override fun onDestroy() {
super.onDestroy()
beatBox.release()
}
十一、深入学习:整合测试
-
单元测试中,受测对象是单个类。保证各个类单元正确运行,相互之间的交互符合预期。
-
整合测试中,受测对象是应用的一部分,包括协同工作的众多对象。验证受测各部分已正确整合在一起,按预期发挥作用。在 Android 平台上,整合测试通常还是指 UI 级别的测试(和UI部件交互,验证它们的行为表现是否符合预期)。常以 instrumentation 测试来实施。
Espresso 是 Google 开发的一个 UI 测试框架,可用来测试 Android 应用。通常新项目都会自动的引用这个依赖。
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 运行时环境支持。
activityRule 上的 @get:Rule 注解告诉 JUnit,运行测试前,要启动一个 MainActivity 实例。
onView(withText(“65_cjipie”)) 会找到显示 “65_cjipie” 的视图,对其执行测试。
check(matches(isDisplayed())) 用来判定视图在屏幕上看得见。
有关 Espresso 详情参考:
developer.android.com/training/te…
十二、深入学习:模拟对象与测试
模拟对象假扮成其他不相干的组件,为的就是隔离受测对象。对于单元测试来说,能快速创建模拟对象的 Mockito 非常有用。
但是整合测试时,最好避免使用像 Mockito 这样的自动模拟测试框架,因为模拟太重了,需要很多整合测试共享,太繁琐。
**基本原则:**模拟对象的效用不应超出受测组件的边界。应着重关注测试范围,防止测试越界。
十三、挑战练习:播放进度控制
给 BeatBox 应用添加播放进度控制功能,在MainActivity中,使用SeekBar部件控制SoundPool的play(Int, Float, Float, Int, Int, Float)函数的播放速率参数值。
参考 Demo,指不定啥时候就更新了。O(∩_∩)O哈哈~
十四、挑战练习:设备旋转问题
给 BeatBox 应用添加一个 Jetpack 版 ViewModel,实现在设备旋转时保存BeatBox对象。
参考 Demo,指不定啥时候就更新了。O(∩_∩)O哈哈~
其他
BeatBox 项目 Demo 地址:
🌈关注我吖~❤️
公众号:妮K妮K妮
A%2F%2Fgithub.com%2Fvisiongem%2FAndroidGuideApp%2Ftree%2Fmaster%2FBeatBox “https://github.com/visiongem/AndroidGuideApp/tree/master/BeatBox”)
🌈关注我吖~❤️
公众号:妮K妮K妮
最后
有小伙伴私信问Compose的问题,好不好用啊,现在要不要学啊?
其实答案很简单,自从谷歌2019年公布了声明式UI框架Jetpack Compose后,两年多的时间,各种大力宣传,和大量资源的倾斜,API功能都趋于稳定了。
至于好不好用,各种用过的同行都是持肯定态度的。优势大概就是这四点:
强大的工具和直观的Kotlin API
简化并加速了Android上的UI开发
可以帮助开发者用更少更直观的代码创建View
有更强大的功能,以及还能提高开发速度
这么大的优势,毋庸置疑,肯定是要学的嘛,而且越快掌握越好。别等刀架到脖子上了,才去练金钟罩。
至于怎么快速上手,可以给大家免费分享一份**《Jetpack Compose 完全开发手册》**,手把手教大家从入门到精通。
第一章 初识 Jetpack Compose
-
为什么我们需要一个新的UI 工具?
-
Jetpack Compose的着重点
加速开发
强大的UI工具
直观的Kotlin API
- API 设计
- Compose API 的原则
一切都是函数
顶层函数(Top-level function)
组合优于继承
信任单一来源
- 深入了解Compose
Core
Foundation
Material
- 插槽API
第二章 Jetpack Compose构建Android UI
- Android Jetpack Compose 最全上手指南
Jetpack Compose 环境准备和Hello World
布局
使用Material design 设计
Compose 布局实时预览
……
- 深入详解 Jetpack Compose | 优化 UI 构建
Compose 所解决的问题
Composable 函数剖析
声明式 UI
组合 vs 继承
封装
重组
……
- 深入详解 Jetpack Compose | 实现原理
@Composable 注解意味着什么?
执行模式
Positional Memoization (位置记忆化)
存储参数
重组
……
第三章 Jetpack Compose 项目实战演练(附Demo)
- Jetpack Compose应用1
开始前的准备
创建DEMO
遇到的问题
- Jetpack Compose应用2
- Jetpack Compose应用做一个倒计时器
数据结构
倒计时功能
状态模式
Compose 布局
绘制时钟
- 用Jetpack Compose写一个玩安卓App
准备工作
引入依赖
新建 Activity
创建 Compose
PlayTheme
画页面
底部导航栏
管理状态
添加页面
- 用Compose Android 写一个天气应用
开篇
画页面
画背景
画内容
……
- 用Compose快速打造一个“电影App”
成品
实现方案
实战
不足
……
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
有需要的话可以点下面二维码免费领取↓↓↓