写在开头

突然想把最近工作中研究的自动化测试总结一下了,期间也是伴随着查各种资料,不过还是有坑需要自己填,不过一篇文章应该也写不清楚吧。

一、单元测试及其必要性

   先说一些比较官方的概念,测试这门技术相信大学期间学过软件工程这门课的都很熟悉,初次看见能够用代码实现对代码的测试还是感觉很神奇的,虽然之后就没用过了。没错单元测试本质上就是检测代码正确性的代码,一般由开发人员编写。单元测试在实际项目开发中还是有它的必要性的,如代码优化,第一手的文档,在Android中更能节省迭代的时间。也是由于需要去写代码并且工作量不亚于实际项目中的编码量,导致了开发人员很少去重视。

二、Android的单元测试

   现在开发Android项目应该都是使用Android Studio(AS)这个编译器了,本文也主要是围绕它来讲解。首先从项目创建和目录结构讲起。

2.1 AS创建Android项目

  应该所有人都注意过,使用AS创建的Android项目之后src下会有三个根目录分别是androidTest、main和test。

  其中main里面就是主工程项目的文件,另外两个文件都是和测试相关,他们区别主要是第三方库的引用上的不同,查看build.gradle文件可见如下:

  使用implementation导入的库在main主项目中使用,testImplementation导入的库在test项目中使用,androidTestImplementation导入的库在androidTest项目中使用。注意,这里的AS版本是3.x,implementation和api是最新的导入库的关键字,如果是2.x版本还是原来的compile。也就是说junit这个库只能在test中使用,espresso只能在androidTest目录中使用,也曾经试过两种方式导入junit,效果如何可以自行体会。

2.2 一个Junit的例子

   这个例子是改造了test目录下默认的ExampleUnitTest测试类,为它在主工程下添加了一个被测试类ExampleUnit。

//main目录下的被测试类public class ExampleUnit {    public static int add(int a, int b) {        return a + b;    }}//test目录下改造之后的测试类public class ExampleUnitTest {    @Test    // 1     public void addition_isCorrect() throws Exception {        assertEquals(4, ExampleUnit.add(2, 2));  // 2    }}

  代码注释1处是Junit的注解,代表这个方法是个测试用例,一个测试类中可以用n个测试用例;注释2处是期望值和实际值的对比,assertEquals的第一个参数是期望值,第二个参数是实际值,这里调用了被测试类的add方法得到实际值,如果两个值相等该测试用例通过测试。

2.3 Robolectric单元测试

  Robolectric是一个使用Android SDK的单元测试框架,可以用于Android程序的测试驱动开发。简单来说就是在JVM环境中运行Android的程序,不需要安装apk也不需要Android设备,能够做到快速测试。

testImplementation 'org.robolectric:robolectric:3.6.1'

  官网上的使用介绍就是上面那样的,可能最新版本包括了所有需要的库了,旧版本使用的时候还要额外的相关库,具体的可以去Maven Repository查看。其实这个库在单元测试时也是使用Junit架构的,额外的支持了Android SDK,比如四大组件啊和Android常用的api。
   Robolectric特点就是可以直接对四大组件进行单元测试,无需外接任何模拟器和真机设备,这里就以常见的Activity为例。涉及到Activity,首先就会想到布局文件,测试的时候控件的使用是离不开的,为了能够使用这些资源,需要在gradle中额外添加支持的代码。

android {    ...    testOptions {        unitTests {            includeAndroidResources = true        }    }}

  Activity里面的代码就不贴出来了,就是点击一个Button然后弹出一个Toast,测试的内容就是这个Toast是否弹出并且显示的内容是我们想要的。

@RunWith(RobolectricTestRunner.class) // 1public class MainActivityTest{    @Before    public void setUp() throws Exception {        ShadowLog.stream = System.out;   // 2    }    @Test    public void test() throws Exception {        MainActivity activity = Robolectric.setupActivity(MainActivity.class); // 3        activity.findViewById(R.id.button).performClick();  // 4        Log.i(TAG, ShadowToast.getTextOfLatestToast());        assertEquals("This is MainActivity", ShadowToast.getTextOfLatestToast());   // 5    }}
  • 注释1,含义就是测试使用的框架是Robolectric,其他的还有诸如AndroidJUnit4.class这个可以见androidTest文件夹下默认创建的测试类;
  • 注释2,可以把System.out输出的流转换成log,这是Robolectric提供的功能,更符合Android的代码编写风格,Before注解代表了这个方法会在所有测试用例之前执行。
  • 注释3,获取MainActivity的实例。
  • 注释4,获取Button的id并实现点击处理。
  • 注释5,getTextOfLastestToast()可以获取Toast显示的内容,为了更好的演示特意使用log输出这个Toast内容
      最终的测试结果如下,那三个警告可以先忽略不计,测试用例显示为蓝色证明测试通过了。

三、Gradle的自动化测试

   以上讲的一些例子,虽说已经能够实现单元测试,而且在一个测试类中写上数个测试用例(即方法)已经能够达到一定程度的自动化,但是和真正的让程序自己自动化去测试同时生成测试报告并打包成apk还未达到,这里就重点讲这个了。Gradle的命令中可以实现自动化运行所有的测试用例
   在Android项目编译的时候其实Gradle进行N多个Task的运行,这也是使用Gradle之后编译程序速度略慢的一个原因吧,可以点开Gradle栏(一般默认在右上角)查看有什么Task,这里主要介绍和测试有关的。

  这里可以比较明显的看到几个带有Test的Task,明白androidTest和test区别也就知道这里的区分了,connectedAndroidTest是运行androidTest目录下的测试用例,test任务运行test目录下的测试用例,单独运行这两个task就可以得到测试报告了。可以直接AS的终端运行gradlew test,假设一切正常没有出错,会在build目录下得到新的文件。

   reports文件夹下的内容就是测试报告了,test-results也是新生成的,不过内容不需要关注。点开index.html就可以查看测试报告了,差不多就是下面这样的。

四、总结

  本篇讲了AS下的单元测试如何去实现并且利用Gradle生成测试报告,下一篇可以利用jacoco插件生成代码覆盖率报告,并且在持续集成工具jenkins上实现真正的自动化测试。特别要说明一下,以上实验环境的搭建是AS3.x版本适用,低版本的具体配置会有不同。

更多相关文章

  1. tcping测试服务器TCP端口
  2. Android中MVP模式实战版(一)
  3. Android仿360卫士布局风格
  4. 主题:四,android四大组件基础介绍及打电话,发短信简单应用 &单元测
  5. 学习android, 自己编的一个黑白棋游戏 (提供源代码下载)
  6. android项目创建xml和存储xml文件
  7. Android实现双向滑动特效的实例代码
  8. Android(安卓)完整地操作数据库--日记本实例
  9. 浅浅的介绍一下android里面Handler、Looper、Message和MessageQu

随机推荐

  1. Android(安卓)中文 SDK —— ADT 14.0.0
  2. Android(ViewPager中的ViewPager)ViewPager
  3. Android探索之旅(第三十二篇)Android(安卓)
  4. Android(安卓)图形系统剖析
  5. 【Android】数据存储之Network
  6. 农民伯伯的2013
  7. 理解 Android(安卓)Build 系统
  8. android 各个span类详解--用于富文本编排
  9. android button background图片被拉伸
  10. android 中文api (84) ―― TrafficStats