您的位置:首页 > 移动开发 > Android开发

Android本地单元测试教程(Kotlin版本)

2017-09-30 16:59 267 查看

前言

单元测试是属于程序开发的一个比较重要的阶段,甚至说比代码的实现更为重要.

在面向对象开发的语言中,单元测试是非常重要的一项内容,那为什么现在大部他程序员都不太喜欢去写单元测试的内容呢,原因很简单,那是因为大部分人认为没有必要,觉得功能实现就可以了,对于我来说,我之前也是也种心态,最根本的原因还是因为懒.那为什么我现在要提到单元测试,而且还要写一篇博客呢,也是因为同一个原因:懒!

对于简单的项目还好,不复杂的逻辑和不太多的模块的这类项目,不用单元测试也能正常的完成开发,但是当遇到一些程序实现逻辑复杂的,模块之间耦合较多的工程时,没有单元测试的情况下,你去修改任何一处代码,都将花费巨大的心力和时间的代价去进行完整的测试,而且每一次修改都必须都要经历这些.但是如果你之前有写好单元测试,那每当你修改完一处代码,只要对这代码相关的测试单元进行运行一遍,基本就能校验出代码修改的结果是否会影响到原来的功能逻辑,而且不再次去进行整体的安装运行点击这些耗时,大开销测试了,测试非常轻松,都不用费脑子去想代码修改带来的种种可能性,好的坏的影响等等,这就是为什么我要写这篇博客的原因,也希望更多的人能够开始把单元测试放在心上,开始写起单元测试的代码.

另一方面,站在面向对象开发的思想上,面向抽象的开发的步骤也是以下四步:

1. 定义接口

2.编写用例(单元测试,满足之前定义的角色)

3.实现接口功能

4.检验实现是否能满足用例的需求

单元测试是在第二步,也就是说在你写代码之前,就应该要先把单元测试做好.

Android基础本地单元测试

基础的单元测试就是指纯java代码在本地电脑上运行测试,这里我以Kotlin代码为例.

我们就按照前文说的四步步骤来开始我们的单元测试编码之路.

我们就举一个简单的功能需求来实现一份完整单元测试:校验邮箱格式的正确性.

单元测试环境搭建:

我们新建一个Android工程,默认就会给我们带上单元测试的环境,下图红色方框中的目录便是我们的单元测试的代码目录.



一.定义接口

接口的功能主要就是对邮箱地址进行格式校验,如下定义:

interface IEmailInvalidate {

/**
* 校验邮箱的合法性
*/
fun invalidateEmail(email: String):Boolean

}


并指定一个类来继承接口,方便编写测试用例:

class EmailValidator : IEmailInvalidate {
override fun invalidateEmail(email: String): Boolean {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}

}


这个接口代表我们要完成一个功能,就是对邮箱地址的校验,合法返回True,不合法,返回False

二.编写测试用例代码

测试用例代码的编写我们需要使用到Junit测试框架,在Android工程生成的时候会被自动引入:



编写的测试代码如下:

class EmailValidatorTest {

val emailValidator:EmailValidator = EmailValidator()

@Test
fun emailValidator_CorrectEmailSimple_ReturnsTrue() {
assertTrue(emailValidator.invalidateEmail("name@email.com"))
}

@Test
fun emailValidator_CorrectEmailSubDomain_ReturnsTrue() {
assertTrue(emailValidator.invalidateEmail("name@email.co.uk"))
}

@Test
fun emailValidator_InvalidEmailNoTld_ReturnsFalse() {
assertFalse(emailValidator.invalidateEmail("name@email"))
}

@Test
fun emailValidator_InvalidEmailDoubleDot_ReturnsFalse() {
assertFalse(emailValidator.invalidateEmail("name@email..com"))
}

@Test
fun emailValidator_InvalidEmailNoUsername_ReturnsFalse() {
assertFalse(emailValidator.invalidateEmail("@email.com"))
}

@Test
fun emailValidator_EmptyString_ReturnsFalse() {
assertFalse(emailValidator.invalidateEmail(""))
}

}


邮箱校验用例尽可能包含你所能想到的可能性,这样的测试才能更加全面,也能更加保证我们的实现是稳定且可用的.

代码的测试用例中我们对如下几种情况的邮箱进行校验:

1.合法正常的邮箱格式.2.有二级域名的合法邮箱格式.3.非域名的非法邮箱.4.域名非法的邮箱.5.无用户名的非常邮箱

解释下代码中的唯一注解:

@Test :

这句注解在此处作用的对象是一个方法体,代表被注解的方法体是一个可以被运行的测试体,有了这个注解我们就能直接点击注解左边的运行小图标进行测试的运行.



好了,测试用例编写完毕.

三.实现功能代码

接下来就要对这个接口进行实现了,在我们定义继承类里来实现内部功能

利用Kotlin代码的特性简化后结果如下:

class EmailValidator : IEmailInvalidate {

val emailPatternString = """[a-zA-Z0-9\+\.\_\%\-]{1,256}\@[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}(\.[a-zA-Z0-9][a-zA-Z0-9\-]{0,25})+"""
override fun invalidateEmail(email: String): Boolean = email.matches(Regex(emailPatternString))

}


四.校验

运行测试用例,查看是否有满足所有用例的需求

运行方式有以下几三种:

1.直接点击测试方法体左边的运行小按钮,去运行每一个测试体.

2.直接点击测试类的类名左边的运行小按钮,去整体运行整个类里的所有测试体

3.右击测试代码的包名.点击运行’Run Test in…’去运行整个包下所有类的所有测试体

我们直接选用第二种 ,测试运行结果如下:



Ok,全部测试通过,达到我们的目的了.

当有校验失败的时候会相应的提示红色的失败信号.

代码的工程目录如下:



五.后续

有时候当我们依赖Android系统库里的代码编写测试用例运行测试的时候会直接抛出异常,类似:

RuntimeException(“Stub!”)这种错误.报这个错误的原因是因为我们用于运行本地测试用例的android的jar包是一个被修改版本的jar包,这个jar包本意上只是给开发者提供编译,并不提供运行依赖,若要依赖Android jar包里的功能有两种方案:

1.将测试代码部署到Android手机上进行运行,也就是对应于测试文件夹(AndroidTest)

2.使用mockito框架,对需要依赖的Android 系统库功能进行模拟返回数据,这样就可以不用依赖Android系统运行环境了,如果能使用这种方法,当然还是使用这种方案好,为什么呢,因为这种方案运行快,时间开销小,效率高.

下一章继续讲解关于mockito库的使用进行关于安卓系统库的依赖测试用例代码的编写.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息