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,代表测试成功。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2jjQOJw0-1639124297064)(E:DocumentationMy_Learn_Documentation_Gitandroidpic_androidrun_result.png)]

​ 那如果把Assert.assertTrue("error TEST_LONG", createdFromParcel.longValue == TEST_LONG)改为Assert.assertTrue("error TEST_LONG", createdFromParcel.longValue == 0L呢?
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mltP6P50-1639124297064)(E:DocumentationMy_Learn_Documentation_Gitandroidpic_androidrun_error.png)]

​ 可以看到巨大的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对应的左侧会存在执行的按钮,点击执行即可。

结果

此时查看结果,如下所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QGtwU0nE-1639124297065)(E:DocumentationMy_Learn_Documentation_Gitandroidpic_androidall_run_result.png)]

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>