Activity单元测试Instrumentation入门

前言

我们用Android Studio创建一个新的项目的时候,会发现在main目录的同级有两个目录test和androidTest,这两个就是单元测试代码,其中androidTest下就是Instrumentation测试代码。

今天我们来看看Instrumentation的简单使用。

已有项目

上面是新建项目的情况,如果是已有项目该如何添加单元测试?

首先要依赖相关的几个库,如下:

testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

然后要在build.gradle中添加testInstrumentationRunner

android {
    compileSdk 31

    defaultConfig {
        applicationId "com.xxx.junittest"
        minSdk 21
        targetSdk 26
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    
    ...

然后在src目录下创建新的目录,在创建窗口中直接选择“androidTest/java”这个选项即可

image.png 创建目录后在该目录下创建package(与应用包名相同),然后就可以创建测试类编写代码了。

测试类

一个简单的例子如下:

@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
    @Test
    fun useAppContext() {
        // Context of the app under test.
        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        assertEquals("com.xxxx.junittest", appContext.packageName)
    }
}

这里通过InstrumentationRegistry.getInstrumentation().targetContext来获取应用的Context,然后校验报名。

运行测试

可以测试整个类,也可以测试单个函数,如下

image.png

图中是测试useAppContext这个函数,测试结果如下

image.png

因为我测试的包名不对,所以本次测试的结果是失败的。

测试Activity

下面我们来看一个更复杂的例子,我们需要打开一个页面,然后获取页面一个文本并检查是否正确,代码如下:

@Test
fun startMain(){
    val appContext = InstrumentationRegistry.getInstrumentation().targetContext
    val intent = Intent(appContext, MainActivity::class.java)
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    val activity = InstrumentationRegistry.getInstrumentation().startActivitySync(intent)
    val textView = activity.findViewById<TextView>(R.id.textview)
    assertEquals("hello", textView.text)
}

这里我们用startActivitySync来启动页面,然后获取id是R.id.textview的TextView,并检查其文本。

在测试过程中出现一个问题,运行这段代码一直不成功,报错如下:

java.lang.RuntimeException: Could not launch intent Intent { flg=0x14000000 cmp=com.xxx.junittest/.MainActivity } within 45000 milliseconds. Perhaps the main thread has not gone idle within a reasonable amount of time? There could be an animation or something constantly repainting the screen. Or the activity is doing network calls on creation? See the threaddump logs. For your reference the last time the event queue was idle before your activity launch request was 1651831105045 and now the last time the queue went idle was: 1651831105045. If these numbers are the same your activity might be hogging the event queue.

at androidx.test.runner.MonitoringInstrumentation.startActivitySync(MonitoringInstrumentation.java:490)

网上说是Android Studio的HotSwap功能导致的,但是关闭也不行,最后发现是手机问题,在小米手机上就报错,换成一个华为手机就可以了。

保持Activity打开

运行上面的代码可以发现activity只打开一瞬间就关闭了,如果我们想让activity保持打开的状态以便做一些操作呢?其实很简单,加一个sleep就可以了,如下:

@Test
fun startMain(){
    val appContext = InstrumentationRegistry.getInstrumentation().targetContext
    val intent = Intent(appContext, MainActivity::class.java)
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    InstrumentationRegistry.getInstrumentation().startActivitySync(intent)
    sleep(5000)
}

这样页面打开后就会停留5秒。

总结

后续我们可以利用Instrumentation创建更多的测试,以便完善我们的应用。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

猜你喜欢

转载自blog.csdn.net/m0_56255097/article/details/131070930
今日推荐