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构建一个高效词汇表

《基于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处理:文档工厂的智能生产线三、邮件自动化:

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

python多线程并发测试过程

《python多线程并发测试过程》:本文主要介绍python多线程并发测试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、并发与并行?二、同步与异步的概念?三、线程与进程的区别?需求1:多线程执行不同任务需求2:多线程执行相同任务总结一、并发与并行?1、

一文教你Java如何快速构建项目骨架

《一文教你Java如何快速构建项目骨架》在Java项目开发过程中,构建项目骨架是一项繁琐但又基础重要的工作,Java领域有许多代码生成工具可以帮助我们快速完成这一任务,下面就跟随小编一起来了解下... 目录一、代码生成工具概述常用 Java 代码生成工具简介代码生成工具的优势二、使用 MyBATis Gen

Python使用Reflex构建现代Web应用的完全指南

《Python使用Reflex构建现代Web应用的完全指南》这篇文章为大家深入介绍了Reflex框架的设计理念,技术特性,项目结构,核心API,实际开发流程以及与其他框架的对比和部署建议,感兴趣的小伙... 目录什么是 ReFlex?为什么选择 Reflex?安装与环境配置构建你的第一个应用核心概念解析组件

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Python+wxPython构建图像编辑器

《Python+wxPython构建图像编辑器》图像编辑应用是学习GUI编程和图像处理的绝佳项目,本教程中,我们将使用wxPython,一个跨平台的PythonGUI工具包,构建一个简单的... 目录引言环境设置创建主窗口加载和显示图像实现绘制工具矩形绘制箭头绘制文字绘制临时绘制处理缩放和旋转缩放旋转保存编