Android测试系列之三 - 构建仪器单元测试

2024-05-19 09:38

本文主要是介绍Android测试系列之三 - 构建仪器单元测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


Android测试系列之一 - 测试分类(节选)

Android测试系列之二 - 构建本地单元测试

Android测试系列之三 - 构建仪器单元测试



仪器单元测试,它是运行真机或者模拟器上进行测试,它有一个好处就是它们可以调用Android framework层的APIs以及

supporting APIs,比如:Android Testing Support Library。如果你需要去访问仪器的相关信息(比如目标app的Context)

或者它们需要Android framework层组件的实体(比如Parcelable或者SharedPreferences对象)。


使用仪器单元测试可以让其省去 编写和维护mock 部分的代码。当然,如果你想要的话,你仍然可以继续去使用模拟框架

去模拟任何依赖关系。


搭建测试环境

在Android Studio工程中,你必须将你的仪器测试的源文件放入到  module-name/src/androidTests/java/目录下。


在开始之前,你需要 download the Android Testing Support Library Setup ,它提供了一些APIs,能够让你的

app很快地构建和运行仪器测试代码。The Testing Support Library 包含了一个JUnit 4 test runner (AndroidJUnitRunner)

以及用于UI测试的API (Espresso  UI Automator )


为了能够在你的工程中使用 The Testing Support Library  提供的 the test runner 和 APIs,你需要配置一下Android 测试

的依赖。为了简化测试的开发,你还应该把 Hamcrest 库包含进来,通过使用the Hamcrest matcher APIs,它能够

让你编写出更加灵活的断言。


在你app的build.gradle文件中,你需要指定以下这些库作为一种依赖:

dependencies {androidTestCompile 'com.android.support:support-annotations:24.0.0'androidTestCompile 'com.android.support.test:runner:0.5'androidTestCompile 'com.android.support.test:rules:0.5'// Optional -- Hamcrest libraryandroidTestCompile 'org.hamcrest:hamcrest-library:1.3'// Optional -- UI testing with EspressoandroidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'// Optional -- UI testing with UI AutomatorandroidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
}

注意:

如果你的编译配置文件中,因为support-annotations库包含进了一个compile 的依赖,又因为 espresso-core

包含进了一个androidTestCompile 依赖,那么,你编译时就有可能会出错,因为依赖发生了冲突。那么,此时这个

问题的解决办法就是:将espresso-core 库的依赖升级如下:

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {exclude group: 'com.android.support', module: 'support-annotations'
})
为了使用 JUnit 4测试类,在你的工程中,你需要在app module的build.gradle文件中进行如下设置,去指定  AndroidJUnitRunner  

作为一个默认的test instrumentation runner :

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

创建一个仪器单元测试类

你的仪器单元测试类应该被写为一个 JUnit 4 测试类,为了了解更多关于如何创建 JUnit 4 测试类以及如何使用JUnit 4

断言和注释,可以参考Create a Local Unit Test Class.

为了创建一个JUnit 4 测试类,你要在测试类定义的开头添加  @RunWith(AndroidJUnit4.class) 注释。你还需要

去指定Android Testing Support Library提供的 AndroidJUnitRunner类作为你默认的 test  runner。在 Getting Started with Testing

可以看到更多关于这一步的详细信息。


下面这个示例展示了如何编写一个仪器单元测试去测试关于LogHistory类的Parcelable接口是否被正确地予以实现:

import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.util.Pair;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.List;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;@RunWith(AndroidJUnit4.class)
@SmallTest
public class LogHistoryAndroidUnitTest {public static final String TEST_STRING = "This is a string";public static final long TEST_LONG = 12345678L;private LogHistory mLogHistory;@Beforepublic void createLogHistory() {mLogHistory = new LogHistory();}@Testpublic void logHistory_ParcelableWriteRead() {// Set up the Parcelable object to send and receive.mLogHistory.addEntry(TEST_STRING, TEST_LONG);// Write the data.Parcel parcel = Parcel.obtain();mLogHistory.writeToParcel(parcel, mLogHistory.describeContents());// After you're done with writing, you need to reset the parcel for reading.parcel.setDataPosition(0);// Read the data.LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel);List<Pair<String, Long>> createdFromParcelData = createdFromParcel.getData();// Verify that the received data is correct.assertThat(createdFromParcelData.size(), is(1));assertThat(createdFromParcelData.get(0).first, is(TEST_STRING));assertThat(createdFromParcelData.get(0).second, is(TEST_LONG));}
}

创建一个测试套件

为了组织多个仪器单元测试的执行,你可以将多个测试类组织在一起,放入一个测试套件中,然后一起运行这些测试类。

测试套件可以嵌套。你的测试套件也可以和其他测试套件组合在一起,然后再一起去运行所有的测试类。


一个测试套件是被包含在一个测试包中,类似于 main application package。按照惯例,这个测试包通常以 .suite作为后缀

(比如:com.example.android.testing.mysample.suite)。


为了在单元测试中创建一个测试套件,需要导入 the JUnit  RunWith and Suite 类在你的测试套件中,还需要

添加  @RunWith(Suite.class)  @Suite.SuitClasses() 注释。在 @Suite.SuitClasses() 中列出了单独

的测试类或测试套件作为参数。


下边这个例子展示了如何一个名为UnitTestSuite的套件是如何被实现的,这个套件将CalculatorInstrumentationTest 

CalculatorAddParameterizedTest 测试类组合在了一起,然后予以运行:

import com.example.android.testing.mysample.CalculatorAddParameterizedTest;
import com.example.android.testing.mysample.CalculatorInstrumentationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;// Runs all unit tests.
@RunWith(Suite.class)
@Suite.SuiteClasses({CalculatorInstrumentationTest.class,CalculatorAddParameterizedTest.class})
public class UnitTestSuite {}

运行仪器单元测试

为了运行仪器测试,需要遵循以下几个步骤:


1>确保你的工程已通过按钮 Sync Project进行了同步


2>以其中的一种方式去运行你的测试文件

I>运行单个测试,需要打开 Project 窗体,然后右键点击 测试文件,然后 单击 Run

II>测试一个类的所有方法,需要在测试文件中右键点击这个类或方法,然后单击 Run

III>为了运行一个目录下的所有测试,右键单击这个目录,然后选择 Run tests




参考:

《Building Instrumented Unit Tests》



附加的测试示例:

在需要获取应用的上下文信息时,大家可以通过 InstrumentationRegistry.getTargetContext() 获取的应用的上下文,示例如下:

package com.example.administrator.safecenter;

import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import com.example.administrator.safecenter.db_dao.BlackNumberDao;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertEquals;

/**
 *
 * 版权:XXX公司 版权所有
 *
 * 作者:will smith
 *
 * 版本:1.0
 *
 * 创建日期:2016/9/10
 *
 * 描述:
 *
 * 修订历史:
 *
 */
 
@RunWith(AndroidJUnit4.class)
public class DatabaseTest {/***
     * InstrumentationRegistry.getTargetContext()去获取上下文;
     *
     * BlackNumberDao:是自己用来测试的一个数据库操作的类;
     */
    @Test
    public void test(){BlackNumberDao dao = new BlackNumberDao(InstrumentationRegistry.getTargetContext());
        dao.add("12345678902","2");
        assertEquals(String.valueOf(1), dao.findNumberMode("12345678902"));
    }}

运行结果:



分析:

在代码中,我们用字符串“1”与我们插入的数据库中的模式位字符串“2”进行比较,

从测试报错信息:expected:<[1]> but was:<[2]> 可以看出,我们数据库添加的操作是没有问题的;

这篇关于Android测试系列之三 - 构建仪器单元测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/995774

相关文章

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

深入浅出SpringBoot WebSocket构建实时应用全面指南

《深入浅出SpringBootWebSocket构建实时应用全面指南》WebSocket是一种在单个TCP连接上进行全双工通信的协议,这篇文章主要为大家详细介绍了SpringBoot如何集成WebS... 目录前言为什么需要 WebSocketWebSocket 是什么Spring Boot 如何简化 We

Spring Boot Maven 插件如何构建可执行 JAR 的核心配置

《SpringBootMaven插件如何构建可执行JAR的核心配置》SpringBoot核心Maven插件,用于生成可执行JAR/WAR,内置服务器简化部署,支持热部署、多环境配置及依赖管理... 目录前言一、插件的核心功能与目标1.1 插件的定位1.2 插件的 Goals(目标)1.3 插件定位1.4 核

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

使用Python进行GRPC和Dubbo协议的高级测试

《使用Python进行GRPC和Dubbo协议的高级测试》GRPC(GoogleRemoteProcedureCall)是一种高性能、开源的远程过程调用(RPC)框架,Dubbo是一种高性能的分布式服... 目录01 GRPC测试安装gRPC编写.proto文件实现服务02 Dubbo测试1. 安装Dubb

Python的端到端测试框架SeleniumBase使用解读

《Python的端到端测试框架SeleniumBase使用解读》:本文主要介绍Python的端到端测试框架SeleniumBase使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录SeleniumBase详细介绍及用法指南什么是 SeleniumBase?SeleniumBase