越写悦快乐之Android应用如何接入单元测试
今天的越写悦快乐之系列文章为大家带来Android应用如何接入单元测试。我们都知道软件测试在软件的生命周期中有着举足轻重的位置,不仅仅是因为测试是软件质量的保障,更是因为随着软件产品或者服务的不断演进,传统的手动测试已经无法满足大规模的软件产品和技术迭代,而软件产品不可避免地会产生问题,因此引入必要的软件测试构建流程体系对于构建大型软件产品或服务是一项必不可少的工作。接下来我为大家分享一下如何在Android应用中接入单元测试。
开发环境
- Window 10.0.17763
- Java 8.0.191
- Android Studio 3.3.2
Gradle 版本
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
Build 版本
dependencies {
classpath "com.android.tools.build:gradle:3.2.1"
}
测试介绍
测试是应用开发过程中不可缺少的一个环节,它可以在应用上架之前尽可能地保证你的应用的正确性、业务功能和可用性。
测试的级别
- Small Tests - 70% - Unit Test
- Medium Tests - 20% - Integration Tests
- Large Tests - 10% - User Interface Tests
测试的优势
- 快速响应软件故障
- 在开发周期中尽早地发现软件缺陷
- 可以快速地优化、构建安全的应用
- 逐步深入的测试可以减少技术债务
接入
添加依赖(app/build.gralde
)
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
// Core library
androidTestImplementation 'androidx.test:core:1.1.0'
// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test:rules:1.1.1'
// Assertions
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.ext:truth:1.1.0'
androidTestImplementation 'com.google.truth:truth:0.44'
// Espresso
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.1'
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.1'
// Hamcrest
androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
// UIAutomator
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
}
为了统一管理依赖库的版本,我们可以在项目的
build.gradle
中定义依赖库的版本,然后在此处使用变量代替依赖库的版本号。
也可使用Robolectric来进行单元测试
可使用Mockito搭建模拟数据进行单一测试
创建项目
项目结构 - 图片来自我的手机我们从上图中可以看到源代码(java
)目录下生成3个不同用途的目录:
-
me.weitao.androidtesting
- 源代码目录 -
me.weitao.androidtesting(androidTest)
- Instrumented Test 目录 -
me.weitao.androidtesting(test)
- Unit Test 目录
我们本文的单元测试中的单元可以是一个类、一个方法、一个模块、一个组件、亦或一个视图,但凡可以测试的对象都可以看做是一个单元测试类。在该测试类下构建测试的初始化环境(setUp
),验证核心功能,触发数据响应,断言(assertions
)数据响应的结果,构建有效即时的单元测试,让你的应用可以单独验证某一个功能或者页面。
编写单元测试类(me.weitao.androidtesting.ExampleUnitTest.java
)
package me.weitao.androidtesting;
import org.junit.Test;
import static org.junit.Assert.*;
public class ExampleUnitTest {
@Test
public void testNumberPlus() {
assertEquals(4, 2 + 2);
}
}
编写工具测试类(me.weitao.androidtesting.ExampleInstrumentedTest.java
)
package me.weitao.androidtesting;
import android.content.Context;
import org.junit.Test;
import org.junit.runner.RunWith;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import me.weitao.androidtesting.test.BuildConfig;
import static org.junit.Assert.assertEquals;
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void testPackageName() {
Context appContext = InstrumentationRegistry.getInstrumentation().getContext();
assertEquals(BuildConfig.APPLICATION_ID, appContext.getPackageName());
}
}
运行测试
- 方法一
以@Test
开头的测试方法可以直接点击方法之前的三角箭头,在编辑器的底部就可以看到运行结果
- 方法二
点击右侧Gradle
窗口,然后查看模块app
下的任务列表,即可看到测试相关的任务名称,点击对应的任务名称即可运行测试
- 方法三
通过终端运行graldlew task test
命令可以达到相同的效果
参考
个人总结
首先,总结一下今天的文章内容,文章从软件测试的基础知识出发,阐述了软件测试的分类,软件测试的优势,最后从实战出发说明了接入单元测试的流程和步骤,那么基于测试驱动开发的业务功能或者应用可以更好地识别开发过程中的软件缺陷,我们可以从黑盒和白盒的角度验证功能的可用性和可访问性,让我们的产品或者服务为客户创造更大的价值,让我们的技术得以提升,服务更多的客户,成就更加美好的未来。若是我的文章对你有所启发,那将是我莫大的荣幸。