【Unit Test】一、Android中的Junit

前言

《论语·学而》中说过,吾日三省吾身

因为各种原因,换过几家公司,有外包,有自研产品,有互联网,也有物联网,令我印象深刻的还是其中一家互联网外包,负责一个德企的项目重构,代码质量规范严格,从代码规范 到 单元测试 到 提交规范,如果其中一环出现问题,代码本地都无法提交。

对于 代码规范 可以参考阿里的开发规范手册

对于 Git提交规范 可以使用git hook定制不同提交时的校验

对于单元测试来而言,可以说是整个环节中最重要的部分了,应该是每个开发同学掌握的必修技能,不仅能保证项目的健壮性,也能减少和测试同学的矛盾,进而保证自己的KPI~

Android中的测试分类

在一个完整的Android项目中,需要测试的点有很多

根据测试类型分类:

  • 功能测试 : 业务逻辑是否按照我需要的方式执行,主要手段通过单元测试
  • 性能测试 : 某个方法的执行效率,多线程阻塞等
  • 兼容性测试 : 应用对设备的最大最小兼容性,适配性

根据测试范围分类:

  • 单元测试小测试仅验证应用的一小部分,例如方法或类。
  • 中型测试介于两个单元之间,用于检查两个或多个单元之间的集成。
  • 业务交互测试,从UI发送事件,到最终的正确业务流

下面内容会从单元测试出发,介绍一下如何在Anroid中的正确的使用单元测试来维护代码健壮性,稳定性。

Android中的单元测试

单元测试概述

  • 定义: 单元测试是针对应用中的最小可测试部分(通常是一个方法或类)的自动化测试。
  • 重要性: 确保代码质量,减少bug,提供快速反馈,促进代码重构。

Android中的单元测试框架

  • JUnit 基于Java的单元测试框架,广泛使用于Java开发中。
  • AndroidJUnit4 基于基于Android开发单元测试框架,广泛使用于Android开发中。
  • Mockito: 一个流行的Java模拟框架,用于模拟依赖和测试交互。
  • Robolectric: 允许在JVM上运行Android单元测试,提供对Android API的模拟。

默认情况下,本地单元测试的源文件位于 module-name/src/test/ 中。当使用 Android Studio 创建新项目时,此目录会自动创建。

  • androidTest 目录应包含在真实或虚拟设备上运行的测试。此类测试包括集成测试、端到端测试,以及仅靠 JVM 无法验证应用功能的其他测试。
  • test 目录应包含在本地计算机上运行的测试,如单元测试。与上述方法不同,这些测试可以是在本地 JVM 上运行的测试。

Junit单元测试的编写

依赖库版本

arduino 复制代码
testImplementation 'junit:junit:4.14-SNAPSHOT'

一般情况下,新项目创建时,会默认依赖

编写方法用例 @Test

通过注释 @Test方法,标记该方法为Test方法,用于测试另外一个方法

assertEquals断言

用于判断两个值是否相等

参数一、期待值

参数二、真实值

测试方法命名规范:

一般情况下,使用should<动作>When<条件>的格式命名,例如:should_return_sum_when_two_number_add 或者像图片里面

运行单元测试

点击方法前面的绿色三角,就会运行测试方法(无需运行android虚拟机)

断言结果如果成功 如图所示 失败 在控制台输出期待值 和 真实得结果值,并在代码区域高亮提示

方法执行前@Before

通常情况下sum() 方法并不会在测试类中,我们想测试某个类中的方法,就需要去创建一个类的实例,可以直接在@Test方法里面去创建,但是当一个类中测试方法过多的时候,每个方法都需要手动创建实例,就会很繁琐,所以可以通过@Before,在方法调用前,去初始化一些示例 和配置

计算器类

KOTLIN 复制代码
public class Calculator {  
  
    public int addition(int number, int numberTwo) {  
    return number + numberTwo;  
    }  

    public int subtraction(int number, int numberTwo) {  
    return number - numberTwo;  
    }  
}

单元测试

KOTLIN 复制代码
class ExampleUnitTest {  
    private lateinit var calculator: Calculator  
    //预置Calculator实例
    @Before  
    fun setUp() {  
        calculator = Calculator()  
    }  

    @Test  
    fun shouldReturnSumWhenTwoNumbersAreAdded() {  
        val result: Int = calculator.addition(2, 3)  
        println("addition result $result")  
        assertEquals(5, result)  
    }  
  
    @Test  
    fun shouldReturnSubWhenTwoNumbersAreSubtraction() {  
        val result: Int = calculator.subtraction(3, 2)  
        println("subtraction result $result")  
        assertEquals(1, result)  
    }
}

其它常见注解

  • @After既然有方法执行前的动作,就有@After,使用方式和Before一样,功能一般情况下用于重置对象里面的一些属性。
  • @BeforeClass 用于标记一个方法在所有测试方法之前运行,并且只运行一次。通常用于一次性的初始化工作。
  • @AfterClass 用于标记一个方法在所有测试方法之后运行,并且只运行一次。通常用于一次性的清理工作。

为一个类新建单元测试

  • 1、在需要测试的类ctrl+shift+T
  • 2、选择Create NewTest
  • 可以选择Junit版本,一般项目自带的都是4,
  • 测试类名
  • 测试类的父类
  • 目标包名
  • 下面一些默认的注解,上面有写
  • 下面是需要为哪些方法生成测试方法
    配置完毕后,点击ok就会自动生成了

运行器

可以通过注解 @RunWith(xx.class) 用于指定当前测试类使用xxx的运行器来运行测试。

BlockJUnit4ClassRunner::class

不需要显式指定,JUnit 4的默使用该运行期。
按照类中定义的顺序执行测试方法。

Parameterized::class

用于参数化测试。
允许你使用不同的参数运行同一个测试方法多次

假设我们想对加法 进行多次验证,每次运行都需要手动去修改参数和结果,这样效率会很低下,这时候就可以使用 @Parameterized运行器,来替我们初始化参数

kotlin 复制代码
@RunWith(Parameterized::class)
class ParameterizedTest(private val a: Int, private val b: Int, private val expected: Int) {

    companion object {
        @JvmStatic
        @Parameterized.Parameters
        fun data(): Collection<Array<Int>> {
            return listOf(
            arrayOf(1, 2, 3),
            arrayOf(2, 3, 5),
            arrayOf(3, 4, 8)
            )
        }
    }

    private lateinit var calculator: Calculator


    @Before
    fun setUp() {
        calculator = Calculator()
    }

    @Test
    fun shouldReturnSumWhenTwoNumbersAreAdded() {
        val result: Int = calculator.addition(a, b)
        println("addition result $result")
        assertEquals(expected, result)
    }
}

当我们运行shouldReturnSumWhenTwoNumbersAreAdded()方法时,系统会根据预置参数 调用三次,并按照array里面的数据进行依次测试。

Suite::class

通过一个类收集并运行多个测试类。

通过上面,我们已经生成多个测试类,当想对测试类里面所有的方法进行验证时,我们需要单独运行测试类上面的按钮,如果想同时对几个测试类做验证时,我们可以通过Suite::class,来整合所有的测试类,进行一次执行

kotlin 复制代码
@RunWith(Suite::class)
@Suite.SuiteClasses(
ExampleUnitTest::class, ParameterizedTest::class
)
class TestSuite

执行结果

其它运行器

除去上面基本的一些运行器以外,还会有一些其他进阶的运行器,例如MockIto,AndroidJunit4,我会在下一篇文章进行详细的讲解~

参考资料

相关推荐
萧大侠jdeps7 分钟前
Vue 3 与 Tauri 集成开发跨端APP
前端·javascript·vue.js·tauri
JYeontu1 小时前
实现一个动态脱敏指令,输入时候显示真实数据,展示的时候进行脱敏
前端·javascript·vue.js
发呆的薇薇°1 小时前
react里使用Day.js显示时间
前端·javascript·react.js
嘤嘤嘤1 小时前
基于大模型技术构建的 GitHub Assistant
前端·github
KeepCatch1 小时前
CSS 动画与过渡效果
前端
跑跑快跑1 小时前
React vite + less
前端·react.js·less
web136885658711 小时前
ctfshow_web入门_命令执行_web29-web39
前端
GISer_Jing1 小时前
前端面试题合集(一)——HTML/CSS/Javascript/ES6
前端·javascript·html
清岚_lxn1 小时前
es6 字符串每隔几个中间插入一个逗号
前端·javascript·算法
胡西风_foxww1 小时前
【ES6复习笔记】Map(14)
前端·笔记·es6·map