由于现阶段Android开发趋于敏捷开发,再加上国内大大小小的互联网公司都在做app,导致很多这会是一个系列,所以如果你看完这篇文章,请看下列文章:

开发人员对单元测试没有基本的概念,但是本篇博文不会为大家讲解什么是单元测试,功能测试,而是讲解如何在Android studio上利用gradle使用现阶段流行的测试框架等。

为了确保app或者library库的质量,有一个完整的测试非常重要。很长一段时间,Android开发工具都缺乏针对完整性测试的支持,但是最近,google为之做了大量的工作,其让开发者做测试变得更加容易了,一些旧的框架更新了版本,新的框架也被加入进来。我们现在不仅可以在Android studio中运行这些测试,甚至可以用gradle通过命令行直接执行。

所以基于此,我们这一章,将会为大家介绍几种测试Android app的方式,我们也会深究之为何gradle可以帮助测试自动化。

这一章节我将遵循以下内容:

  • 单元测试
  • 功能测试
  • 测试覆盖率

单元测试

相信大家都有了单元测试的概念,那么好的单元测试不仅仅能够确保app的质量,同时还可以让新代码开发更加容易。Android studio和gradle android插件默认支持单元测试,但是在你使用它之前,你仍需配置一下。

JUnit

JUnit存活了若干年,在测试界非常流行。其使得测试代码容易编写和维护,但是记住,JUnit只能测试逻辑代码,针对和Android SDK相关的代码并没什么卵用。

在你开始编写junit测试之前,你需要为其新建一个目录。通常呢,这个会被叫做test,其会和你的main文件夹平级。

app
└─── src
├─── main
│ ├─── java
│ │ └─── com.example.app
│ └───res
└─── test
└─── java
└─── com.example.app

你可以在test目录下创建测试类。

我建议你使用JUnit 4,你可以将其作为依赖添加到你的依赖库。

dependencies {
testCompile 'junit:junit:4.12'
}

注意到你使用了testCompile,这意味着该jar包只会在你测试的时候导入apk。

如果你有其他的构建版本呢,而你又只是想为特定版本添加该jar,你只需要这么做:

dependencies {
testPaidCompile 'junit:junit:4.12'
}

当所有的事情都OK了,就是时候开始写测试代码了。下面是简单的测试代码:

import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class LogicTest {
@Test
public void addingNegativeNumberShouldSubtract() {
Logic logic = new Logic();
assertEquals("6 + -2 must be 4", 4, logic.add(6, -2));
assertEquals("2 + -5 must be -3", -3, logic.add(2, -5));
}
}

那么如何跑起来呢,也很简单,运行gradlew test。如果你只是想再特定版本中跑呢,那就加一个呗gradlew testDebug。如果测试失败,gradle将会打印相关错误,如果所有测试成功通过,那么会显示BUILD SUCCESSFUL 。

可能你会说,单个测试用例导致整个测试失败,这样不好,如果你想把整个测试案例都跑一遍,那也很简单啊:

$ gradlew test --continue

执行测试任务不仅仅是跑完所有的测试,而且其还会为你创建一份测试报告,你可以找到它app/build/reports/tests/debug/index.html。这份报告让你能够更快的发现问题,我觉得最重要的是当你将你的测试自动化后,这会非常有用,gradle会为每个构建版本都创建一份测试报告。如果你执行测试成功,你的测试报告会是这个样子:

说了这么多原始的做法,那么看看Android studio怎么运行测试的吧。右键项目或者选择开始按钮。。这个太基础不多说了,运行成功是这个样子:

好了,junit测试讲完了,是不是很简单。

如果你想测试你的关联Android sdk代码怎么办,单元测试不是一个好主意,幸运的是,有多个依赖包供你选择,其中最出名的是Robolectric,其可以让你更方便的测试Android功能,并且还不用在设备或者模拟器上运行。

Robolectric

通过使用Robolectrie,你可以编写测试类,这些类可以使用Android SDK和资源文件,当然其还是跑在jvm上,这会让你测试app更加迅速。

在开始使用Robolectrie之前,你需要添加依赖。注意除了Robolectric依赖,你需要添加JUnit包。

apply plugin: 'org.robolectric'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
testCompile 'junit:junit:4.12'
testCompile'org.robolectric:robolectric:3.0'
testCompile'org.robolectric:shadows-support:3.0'
}

Robolectrie测试类也需要写在test文件夹下,举个例子:

 @RunWith(RobolectricTestRunner.class)
@Config(manifest = "app/src/main/AndroidManifest.xml", sdk = 18)
public class MainActivityTest {
@Test
public void clickingButtonShouldChangeText() {
AppCompatActivity activity = Robolectric.buildActivity
(MainActivity.class).create().get();
Button button = (Button)
activity.findViewById(R.id.button);
TextView textView = (TextView)
activity.findViewById(R.id.label);
button.performClick();
assertThat(textView.getText().toString(), equalTo
(activity.getString(R.string.hello_robolectric)));
}
}

功能测试

神马是功能测试,其是用来测试一个app的多个模块是否能够正常工作。举个栗子,你可以创建一个功能测试来确保你点击某一按钮后是否会有一个新的activity。依然,我们会有很多框架。但是在这里,我推荐Espresso。

Espresso

google创建Espresso的目的就是在于简化开发人员编写功能测试用例。这个包是由Android support repository提供,所以你可以通过SDK Manager使用它。

在运行测试用例之前,你需要定义一个runner。google提供了AndroidJUnitRunner测试runner,这将帮助你在手机上运行Unit测试。测试runner可以帮你安装apk以及一个测试apk,执行所有测试,生成测试报告。

假设你下载了support library包,那么你需要这么定义:

defaultConfig {
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}

当然你需要添加一些依赖包:

 dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
androidTestCompile 'com.android.support.test:runner:0.3'
androidTestCompile 'com.android.support.test:rules:0.3'
androidTestCompile
'com.android.support.test.espresso:espresso-core:2.2'
androidTestCompile
'com.android.support.test.espresso:espresso-contrib:2.2'
}

注意到这些依赖包使用了androidTestCompile,其不同于testCompile。当你直接运行时,会报错:

Error: duplicate files during packaging of APK app-androidTest.apk
Path in archive: LICENSE.txt
Origin 1: .../hamcrest-library-1.1.jar
Origin 2: .../junit-dep-4.10.jar

其意思也很清楚,因为多个文件导致,你可以简单处理下:

 android {
packagingOptions {
exclude 'LICENSE.txt'
}
}

注意:功能测试需要放在AndroidTest目录下,下面是测试用例:

@RunWith(AndroidJUnit4.class)
@SmallTest
public class TestingEspressoMainActivityTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new
ActivityTestRule<>(MainActivity.class);
@Test
public void testHelloWorldIsShown() {
onView(withText("Hello world!")).check
(matches(isDisplayed()));
}
}

功能测试也有测试报告,当正确执行后,应该是这样的:

最后可能有朋友问,在Android studio中执行测试,那就附图吧:

测试覆盖率

一旦你在你的项目中使用到了测试,那么你肯定想知道你的测试覆盖量。很真实,依然有很多测试覆盖率工具,我推荐的是Jacoco。

Jacoco

有一份覆盖率报告,很简单。你只需要配置一下:

buildTypes {
debug {
testCoverageEnabled = true
}
}

当你执行完构建,你可以在app/build/ outputs/reports/coverage/debug/index.html中找到,每个版本都会有一个报告。测试覆盖率会是这样的:

你甚至可以通过点击查看更多信息,可以看到哪一行代码被测试。

总结

在这一章,我们学习了如何测试,我们学习了简单的单元测试,以及Robolectric测试。我们学习了功能测试,以及学习了如何使用Espresso。最好,我们学会了如何查看测试覆盖率报告。

在下一章,我将会带来最重要的一章,即自定义化构建过程,创建自定义tasks和插件。当然了我们会首先介绍Groovy语法,理解其语法让你能够更轻松的理解gradle是如何工作的。

【转载】Gradle for Android 第六篇( 测试)的更多相关文章

  1. Gradle for Android 第三篇( 依赖管理 )

    依赖管理 这会是一个系列,所以如果你还没有看我之前的几篇文章,请先查看以下文章: Gradle for Android 第一篇( 从 Gradle 和 AS 开始 ) Gradle for Andro ...

  2. 【转载】Gradle for Android 第四篇( 构建变体 )

    当你在开发一个app,通常你会有几个版本.大多数情况是你需要一个开发版本,用来测试app和弄清它的质量,然后还需要一个生产版本.这些版本通常有不同的设置,例如不同的URL地址.更可能的是你可能需要一个 ...

  3. 【转载】Gradle for Android 第五篇( 多模块构建 )

    Android studio不仅允许你为你的app和依赖库创建模块,同时也可为Android wear,Android TV,Google App Engine等创建模块,而这些单独的模块又可以在一个 ...

  4. 【转载】Gradle for Android 第三篇( 依赖管理 )

    依赖管理是Gradle最闪耀的地方,最好的情景是,你仅仅只需添加一行代码在你的build文件,Gradle会自动从远程仓库为你下载相关的jar包,并且保证你能够正确使用它们.Gradle甚至可以为你做 ...

  5. 深入理解gradle编译-Android基础篇

    深入理解gradle编译-Android基础篇 导读 Gradle基于Groovy的特定领域语言(DSL)编写的一种自动化建构工具,Groovy作为一种高级语言由Java代码实现,本文将对Gradle ...

  6. 【朝花夕拾】Android自定义View篇之(六)Android事件分发机制(中)从源码分析事件分发逻辑及经常遇到的一些“诡异”现象

    前言 转载请注明,转自[https://www.cnblogs.com/andy-songwei/p/11039252.html]谢谢! 在上一篇文章[[朝花夕拾]Android自定义View篇之(五 ...

  7. 【转】gradle for android 第一篇

    正如大家所见,这是本英文书,而由于国内的gradle翻译资料不全,所以特次开辟专栏,翻译gradle for android这本书,同时添加自己的心得体会以及在实际工作上的实战,希望大家能够喜欢. 如 ...

  8. 第六篇 ANDROID窗口系统机制之显示机制

    第六篇 ANDROID窗口系统机制之显示机制 ANDROID的显示系统是整个框架中最复杂的系统之一,涉及包括窗口管理服务.VIEW视图系统.SurfaceFlinger本地服务.硬件加速等.窗口管理服 ...

  9. Gradle 实现 Android 多渠道定制化打包

    Gradle 实现 Android 多渠道定制化打包 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在项目中遇到需要实现 Apk 多渠道.定制化打包, Google .百度查找了一些资料, ...

随机推荐

  1. C#发送邮件(内容中有图片)

    用微软的System.Net.Mail发送邮件,有些时候发邮件需要邮件内容中添加图片. 对象解释 SmtpClient类:允许应用程序使用简单邮件传输协议 (SMTP) 发送电子邮件.MailAddr ...

  2. API统一管理平台-YApi

    前言:开发过程中,会产生很多接口对接操作,这个时候可能需要一个接口管理平台管理已经开发好的接口方便业务对接. 一.概述 YApi 是高效.易用.功能强大的 api 管理平台,旨在为开发.产品.测试人员 ...

  3. flex下省略号的问题解决

    最近在搞微信小程序,发现flex下使用省略号是没有效果的,而且还会打乱预期的结构,查询statckoverflow知道需要在父级设置min-width:0; 但是在我的尝试下,依然不行,原来在上层父级 ...

  4. js-事件函数调用简化

    // 一般写法 function fn(event) { console.log(event) } div.onclick = function (event) { fn(event) } ===== ...

  5. 【转载】Android IntentService使用全面介绍及源码解析

    一 IntentService介绍 IntentService定义的三个基本点:是什么?怎么用?如何work? 官方解释如下: //IntentService定义的三个基本点:是什么?怎么用?如何wo ...

  6. OC-类似歌词字体颜色逐字变化的实现方法

    预期实效果图如下: 如上图所示,文字的颜色会根据时间的移动,逐字变成绿色. 实现方法:(1)调用方法: 用 void UIRectFillUsingBlendMode(CGRect rect, CGB ...

  7. skip-broken to work around the problem rpm -Va --nofiles --nodigest

    清除yum缓存 yum clean all 重新安装,见结尾[root@localhost ~]# yum install libstdc++.so.6Loaded plugins: fastestm ...

  8. tomcat修改进程名称

    1.window平台: 打开tomcat_home\bin\setclasspath.bat文件,找到set _RUNJAVA=”%JRE_HOME%\bin\java”这一行. 将该行注释掉 ,然后 ...

  9. SSL握手中win xp和SNI的那点事

    SSL握手中win xp和SNI的那点事 一.背景需求server1-3使用不同的域名对外提供https服务,用nginx作为前端负载均衡器并负责https集中解密工作(以用户访问的域名为依据进行流量 ...

  10. go语言设计模式之Concurrency workers pool

    worker.go package main import ( "fmt" "strings" ) type WorkerLauncher interface ...