Android 仪器化单元测试(instrumented unit tests) Androidx kotlin版本

Posted pumpkin的玄学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 仪器化单元测试(instrumented unit tests) Androidx kotlin版本相关的知识,希望对你有一定的参考价值。

前言

近期需要进行单元测试,测试内容需要真机环境,所以需要使用instrumented unit tests,用来在跑在真机上进行测试。

blog用于记录。

简介

仪器化单元测试(instrumented unit tests)是在物理设备和模拟器上运行的测试,它们可以利用 android 框架 API 和支持 API,例如 AndroidX API 、Android framework API 、Android supporting API 等。 仪器化测试比本地单元测试提供更高的保真度,但运行速度要慢得多。

环境配置

  • 如果工程src目录下不存在androidTest/java目录,则需要进行创建该目录,创建步骤如下图所示:

  • 配置build.gradle依赖

    dependencies 
        androidTestImplementation 'androidx.test:runner:1.4.0'
        androidTestImplementation 'androidx.test:rules:1.4.0'
    
    
    android 
        defaultConfig 
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        
    
    

测试样例

测试代码

本例子参考google官方网站。因为官网里面很多类没有给到,所以进行了一波补充完善。➡️➡️➡️➡️点击可前往官网

以下示例显示了如何编写仪器单元测试来验证 Parcelable接口是否被 LogHistory类正确实现:🙆‍♀️

import android.os.Parcel
import android.os.Parcelable
import android.os.Parcelable.Creator
import androidx.test.runner.AndroidJUnit4
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

const val TEST_STRING = "This is a string"
const val TEST_LONG = 12345678L

// @RunWith is required only if you use a mix of JUnit3 and JUnit4.
@RunWith(AndroidJUnit4::class)
class LogHistoryAndroidUnitTest 
    private lateinit var logHistory: LogHistory

    @Before
    fun createLogHistory() 
        logHistory = LogHistory(TEST_STRING, TEST_LONG)
    

    @Test
    fun logHistory_ParcelableWriteRead() 
        val parcel = Parcel.obtain()
        logHistory.apply 
            // 写数据
            writeToParcel(parcel, describeContents())
        

        // 完成写入后,置包裹以进行读取。
        parcel.setDataPosition(0)

        // 读取数据
        val createdFromParcel: LogHistory = LogHistory.CREATOR.createFromParcel(parcel)
        // 验证数据的正确性
        Assert.assertTrue("error TEST_STRING", createdFromParcel.strValue == TEST_STRING)
        Assert.assertTrue("error TEST_LONG", createdFromParcel.longValue == TEST_LONG)
    


class LogHistory(val strValue: String = "", val longValue: Long = 0L) : Parcelable 
    constructor(source: Parcel) : this(source.readString() ?: "", source.readLong())

    companion object 
        val CREATOR: Creator<LogHistory> = object : Creator<LogHistory> 
            override fun createFromParcel(source: Parcel?): LogHistory = LogHistory(source!!)

            override fun newArray(size: Int): Array<LogHistory> = Array(size)  LogHistory() 
        
    

    override fun describeContents(): Int = 0

    override fun writeToParcel(dest: Parcel?, flags: Int) 
        dest!!.writeString(strValue)
        dest.writeLong(longValue)
    

运行

  1. 确保已经链接手机
  2. 点击下图2所示的箭头
  3. 点击run在真机上运行

结果

​ 通过测试结果可以清晰看到状态passed,代表测试成功。

​ 那如果把Assert.assertTrue("error TEST_LONG", createdFromParcel.longValue == TEST_LONG)改为Assert.assertTrue("error TEST_LONG", createdFromParcel.longValue == 0L呢?

​ 可以看到巨大的failed,还可以点开错误日志,看到报错的信息!!!

一键测试所有

以上的测试只能一个一个的点,如果我写好了一堆单元测试,想要一键测试,应该怎么做呢?😮

引入

下面引入@Suite.SuiteClasses

  • 将需要进行一键测试类上方增加@Suite.SuiteClasses注解
  • 新建类的入口,引入需要一键执行的类,并且需要新增@RunWith(Suite::class)与@Suite.SuiteClasses(Class...)注解

举个🌰

  • 我们有两个类都写了单元测试,如下所示:

    @RunWith(AndroidJUnit4::class)
    @Suite.SuiteClasses
    class CalculatorInstrumentationTest 
        @Test
        fun test() 
            Log.i("CalculatorTest", "CalculatorInstrumentationTest")
        
    
    @RunWith(AndroidJUnit4::class)
    @Suite.SuiteClasses
    class CalculatorAddParameterizedTest 
        @Test
        fun test()
            Log.i("CalculatorTest","CalculatorAddParameterizedTest")
        
    
    

    需要在这些类上面新增@Suite.SuiteClasses注解

  • 写测试入口

    @RunWith(Suite::class)
    @Suite.SuiteClasses(
        CalculatorInstrumentationTest::class,
        CalculatorAddParameterizedTest::class
    )
    class UnitTestSuite
    

    注意:此时@RunWith里面的值是Suite::class,使用@Suite.SuiteClasses注解将需要一起执行的类,加入进来即可。

    此时在AS里面class UnitTestSuite对应的左侧会存在执行的按钮,点击执行即可。

结果

此时查看结果,如下所示:

可以看到,我们在两个类的两个测试方法均进行了执行,且是passed状态!!!🦾

以上是关于Android 仪器化单元测试(instrumented unit tests) Androidx kotlin版本的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio导入现有单元测试“无法找到仪器信息”

Android Studio 单元测试配置

在 Android Studio 中运行参数化单元测试时,未找到给定的测试包括错误

有啥解决方案可以解决android上的仪器测试

Android 仪器测试中的 Dagger 2 注入

使用 Gradle 运行特定的 Android 仪器测试