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

相关文章

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

Android DataBinding 与 MVVM使用详解

《AndroidDataBinding与MVVM使用详解》本文介绍AndroidDataBinding库,其通过绑定UI组件与数据源实现自动更新,支持双向绑定和逻辑运算,减少模板代码,结合MV... 目录一、DataBinding 核心概念二、配置与基础使用1. 启用 DataBinding 2. 基础布局

Android ViewBinding使用流程

《AndroidViewBinding使用流程》AndroidViewBinding是Jetpack组件,替代findViewById,提供类型安全、空安全和编译时检查,代码简洁且性能优化,相比Da... 目录一、核心概念二、ViewBinding优点三、使用流程1. 启用 ViewBinding (模块级

基于Python构建一个高效词汇表

《基于Python构建一个高效词汇表》在自然语言处理(NLP)领域,构建高效的词汇表是文本预处理的关键步骤,本文将解析一个使用Python实现的n-gram词频统计工具,感兴趣的可以了解下... 目录一、项目背景与目标1.1 技术需求1.2 核心技术栈二、核心代码解析2.1 数据处理函数2.2 数据处理流程

Python FastMCP构建MCP服务端与客户端的详细步骤

《PythonFastMCP构建MCP服务端与客户端的详细步骤》MCP(Multi-ClientProtocol)是一种用于构建可扩展服务的通信协议框架,本文将使用FastMCP搭建一个支持St... 目录简介环境准备服务端实现(server.py)客户端实现(client.py)运行效果扩展方向常见问题结

详解如何使用Python构建从数据到文档的自动化工作流

《详解如何使用Python构建从数据到文档的自动化工作流》这篇文章将通过真实工作场景拆解,为大家展示如何用Python构建自动化工作流,让工具代替人力完成这些数字苦力活,感兴趣的小伙伴可以跟随小编一起... 目录一、Excel处理:从数据搬运工到智能分析师二、PDF处理:文档工厂的智能生产线三、邮件自动化: