照例,如果自学不需要看我这个博客的话,资料如下:
官网关于Android Test的介绍的地址
Android官方关于测试的例子 ,需要的自取
单元测试、集成测试、黑盒测试、白盒测试等,只有单元测试是我们开发人员需要自己完成的,其余都是由测试人员完成的。单元测试本质上也是代码,是验证代码正确性的代码。
为什么要做单元测试
- 便于后期重构。单元测试为后期测试提供了保障,在重构之后,只要单元测试还是全部通过,那么在很大程度上表示重构没有引入新的bug。
- 优化设计。编写单元测试将使开发者从调用者的角度观察和思考,这样迫使开发者把程序设计成易于调用和低耦合的易测试的形式。
- 避免代码出现回归。编写完成后,可以随时随地快速运行测试,而不是要求将代码部署到设备上,再手动执行覆盖各种路径。
- 文档记录。单元测试是极好的“官方文档”,它展示函数或者类如何使用。
Android 测试类型(选自官网)
测试代码的位置取决于您要编写的测试的类型。 Android Studio 为以下两种测试类型提供了源代码目录(源集):
本地单元测试
位于 module-name/src/test/java/目录。
这些测试在计算机的本地 Java 虚拟机 (JVM) 上运行。 当您的测试没有 Android 框架依赖项或当您可以模拟 Android 框架依赖项时,可以利用这些测试来尽量缩短执行时间。
在运行时,这些测试的执行对象是去掉了所有 final 修饰符的修改版 android.jar。 这样一来,您就可以使用 Mockito 之类的常见模拟库。
Instrumented测试(仪器测试)
位于 module-name/src/androidTest/java/。
这些测试在硬件设备或模拟器上运行。 这些测试有权访问 Instrumentation API,让您可以获取某些信息(例如您要测试的应用的 Context), 并且允许您通过测试代码来控制受测应用。 可以在编写集成和功能 UI 测试来自动化用户交互时,或者在测试具有模拟对象无法满足的 Android 依赖项时使用这些测试。
由于仪器测试内置于 APK 中(与您的应用 APK 分离),因此它们必须拥有自己的 AndroidManifest.xml 文件。 不过,由于 Gradle 会自动在构建时生成该文件,因此它在您的项目源集中不可见。 您可以在必要时(例如需要为 minSdkVersion
指定其他值或注册测试专用的运行侦听器时)添加自己的清单文件。 构建应用时,Gradle 会将多个清单文件合并成一个清单。
Gradle 构建解读这些测试源集的方式与其解读项目应用源集的方式相同,您可以利用这一点根据构建变体创建测试。
以下示意图诠释了两种测试的代码结构(图中1表示的是仪器测试的代码,2表示的是单元测试的代码结构)
Junit4
在Android测试框架中,常用的有以下几个框架和工具类:JUnit4、AndroidJUnitRunner、Mockito、Espresso,其中主要的单元测试使用Junit4。Junit4是一套基于注解的单元测试框架,在Android studio中,编写在test目录下的测试类都是基于该框架实现,该目录下的代码直接运行在本地的JVM上,不需要Android真机或者模拟器支持。常用的注解如下(更多内容可以查看Junit4官网):
- @BeforeClass 测试类里所有用例运行之前,运行一次这个方法。方法必须是public static void
- @AfterClass 与BeforeClass对应
- @Before 在每个用测试例运行之前都运行一次。
- @After 与Before对应
- @Test 指定该方法为测试方法,方法必须是public void
- @RunWith 测试类名之前,用来确定这个类的测试运行器
以下用一个简单的测试类来展示测试类的大概形式:
1 | public class CaculatUtilTest{ |
Junit的断言和失败提示
Junit提供了多个以assert开头的函数,分别用来验证各类相等性质的问题,大致有如下几类:
assertEquals
assertEquals的作用是判断两个值或者对象是否相等。接受2个参数,参数1为预期值,参数2为计算得到的值。
assertTrue 与 assertFalse
assertTrue 与 assertFalse顾名思义就是分别验证真与假,只需要一个boolean类型的参数。例如 assertTrue(false)测试会失败, 而 assertTrue(true) 测试通过。
assertNull 与 assertNotNull
和assertTrue、assertFalse类似,只不过是用来判断空或者非空。例如:assertNull(null) 会测试失败,因为值为null;而assertNull(“hell”)就能测试通过。
assertSame 与 assertNotSame
assertSame用于判断两个对象是否是同一个对象,与assertEquals不同的是,assertSame强调的为同一个对象,而assertEquals只要两个对象相等即可(即调用equals函数时返回true)。
failNotEquals
函数有3个参数,参数1位失败时提示信息,参数2为期望值,参数3是实际值。当两个对象不相等时抛出参数1的错误信息。
failSame与failNotSame
failNotSame与failNotEquals类似,不是同一个对象时就抛出参数1的错误信息。
fail(String) 与 fail()
fail(String)直接抛出当前测试用例参数1中的错误信息,而fail()给出默认的错误信息。
运行多个测试类——TestSuite
如果需要同时运行两个或多个Test类,JUnit提供了Suite注解,在对应的测试目录下创建一个空Test类:
- @RunWith(Suite.class):配置Runner运行环境。
- @Suite.SuiteClasses({A.class, B.class}):添加需要一起运行的测试类。
1 |
|
上述代码中,UnitTestSuite成了一个空类,测试类被添加到注解中了。
或者,如果不用注解,可以通过JUnit4TestAdapter包装测试类,并将JUnit4TestAdapter对象添加到TestSuit中,示例代码如下:
1 | public class MathTestSuite{ |
上述代码有一个静态的suite函数,它返回一个Test对象,这个对象是TestSuite类型的。测试时,以Junit测试用例的形式运行这个MathTestSuite即可运行这两个测试类。
多个参数输入测试
当需要传入多个参数进行测试时,可以使用 @Parameters 来进行单个方法的多次不同参数的测试,对于测试类,使用该方法需要如下步骤:
- 在测试类上添加@RunWith(Parameterized.class)注解
- 添加测试类的构造函数
- 添加获取参数集合的static方法,并在方法上添加@Parameters注解
- 在需要测试的方法中直接使用成员变量,该变量由JUnit通过构造方法生成
直接上示例代码如下:
1 | //为测试类添加注解 |
AndroidJUnitRunner
当单元测试中涉及Android系统库的调用时,可以通过AndroidJUnitRunner方案完成测试,这样就能在测试类中使用Context、parcelable、Shareprefrence等类。使用方法是在androidTest目录下创建测试类(因为这涉及到Instrumented测试的内容),在该类上添加@RunWith(AndroidJUnit4.class)注解。如以下代码示范了如何在测试类中使用SharedPrefrences:
1 |
|
模拟所需要的模块
有时我们测试需要依赖于其他的功能模块,但是某些原因这个功能模块不能在测试时运用或未开发完,为了不阻塞测试,我们可以Mock对象来完成测试。还有一些场景,诸如对象很难被创建、真实对象运行缓慢、真实对象的错误很难出现等,也可以通过Mock对象来测试。
手动Mock对象
举个例子,开发一款记事本软件,登录成功后才能写/存笔记,小明小刘分别负责登录和写/存笔记功能,存笔记的时候时候需要用户信息User的实例,而用户信息在登录成功后才能获得。可行的代码如下:
1 | //保存数据的类 |
使用第三方工具Mockito
前面有例子已经涉及到Mockito的部分使用,可以在网上搜索相关使用,这里不再详细展开,如果需要,后面会专门介绍。
运行单元测试
- 在Android studio中,对指定的测试类点击鼠标右键,选择对应的Run或者debug
- 在Terminal输入gradle testDebugUnitTest或gradle testReleaseUnitTest指令来分别运行debug和release版本的unittesting,在执行的结果可以在xxx\project\app\build\reports\tests\testReleaseUnitTest中查看
声明:整篇文章有部分内容摘抄自博客:https://www.jianshu.com/p/925191464389