Android自动化单元测试(上)

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

写在开头

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

一、单元测试及其必要性

   先说一些比较官方的概念,测试这门技术相信大学期间学过软件工程这门课的都很熟悉,初次看见能够用代码实现对代码的测试还是感觉很神奇的,虽然之后就没用过了。没错单元测试本质上就是检测代码正确性的代码,一般由开发人员编写。单元测试在实际项目开发中还是有它的必要性的,如代码优化,第一手的文档,在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) // 1
public 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版本适用,低版本的具体配置会有不同。

目录
相关文章
|
2月前
|
测试技术 UED Python
探索软件测试的边界:自动化与手动测试的协同
【8月更文挑战第59天】在追求效率和质量的软件生产中,自动化测试与手动测试的辩论从未停止。本文将通过实际案例,揭示二者如何相辅相成,共同构建更健壮的软件测试体系。我们将深入探讨自动化测试的优势、手动测试不可替代的角色以及它们如何在实际项目中协同工作,旨在为读者提供一种平衡的视角来看待软件测试的实践。
128 65
|
2天前
|
测试技术 开发者 UED
探索软件测试的深度:从单元测试到自动化测试
【10月更文挑战第30天】在软件开发的世界中,测试是确保产品质量和用户满意度的关键步骤。本文将深入探讨软件测试的不同层次,从基本的单元测试到复杂的自动化测试,揭示它们如何共同构建一个坚实的质量保证体系。我们将通过实际代码示例,展示如何在开发过程中实施有效的测试策略,以确保软件的稳定性和可靠性。无论你是新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。
|
23天前
|
测试技术
自动化测试项目实战笔记(三):测试用户注册(验证码错误,成功,出现弹框时处理)
本文是关于自动化测试项目实战笔记,主要介绍了如何测试用户注册功能,包括验证码错误、注册成功以及弹框处理的测试步骤和代码实现。
75 2
自动化测试项目实战笔记(三):测试用户注册(验证码错误,成功,出现弹框时处理)
|
23天前
|
测试技术
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
本文介绍了如何使用Pytest和Allure生成自动化测试报告。通过安装allure-pytest和配置环境,可以生成包含用例描述、步骤、等级等详细信息的美观报告。文章还提供了代码示例和运行指南,以及重构项目时的注意事项。
104 1
自动化测试项目学习笔记(五):Pytest结合allure生成测试报告以及重构项目
|
4天前
|
前端开发 数据管理 测试技术
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第27天】本文介绍了前端自动化测试中Jest和Cypress的实战应用与最佳实践。Jest适合React应用的单元测试和快照测试,Cypress则擅长端到端测试,模拟用户交互。通过结合使用这两种工具,可以有效提升代码质量和开发效率。最佳实践包括单元测试与集成测试结合、快照测试、并行执行、代码覆盖率分析、测试环境管理和测试数据管理。
14 2
|
5天前
|
前端开发 JavaScript 数据可视化
前端自动化测试:Jest与Cypress的实战应用与最佳实践
【10月更文挑战第26天】前端自动化测试在现代软件开发中至关重要,Jest和Cypress分别是单元测试和端到端测试的流行工具。本文通过解答一系列问题,介绍Jest与Cypress的实战应用与最佳实践,帮助开发者提高测试效率和代码质量。
18 2
|
3天前
|
Web App开发 设计模式 JavaScript
自动化测试之美:如何利用Selenium实现Web应用的高效测试
【10月更文挑战第29天】在软件开发的世界中,测试是确保产品质量的关键步骤。本文将带你了解如何使用Selenium这一强大的自动化测试工具,提高Web应用测试的效率和准确性。通过实际案例,我们将探索Selenium的核心功能及其在现代软件开发中的应用,旨在帮助读者掌握自动化测试的精髓,从而提升软件测试工作的整体效能。
|
23天前
|
测试技术 数据安全/隐私保护 Python
自动化测试项目实战笔记(四):测试用户登录(账号密码错误,成功,出现弹框等情况)
本文介绍了使用Selenium进行自动化测试时如何测试用户登录的不同情况,包括账号密码错误、登录成功以及处理登录时出现的弹框,并提供了相应的Python代码实现。
39 0
自动化测试项目实战笔记(四):测试用户登录(账号密码错误,成功,出现弹框等情况)
|
23天前
|
测试技术 Python
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
本文介绍了使用Python的unittest框架来加载测试用例的四种方法,包括通过测试用例类、模块、路径和逐条加载测试用例。
50 0
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
|
23天前
|
测试技术 Python
自动化测试项目学习笔记(一):unittest简单运行(初始化,清除,设置测试行为)
本文介绍了Python的unittest框架的基础用法,包括测试初始化(setup)、清除(tearDown)函数的使用,以及assertEqual和assertGreaterEqual等断言方法,并展示了如何创建测试用例,强调了测试函数需以test_开头才能被运行。
52 0
自动化测试项目学习笔记(一):unittest简单运行(初始化,清除,设置测试行为)