Android中使用Robolectric测试点击事件(不需要手机)
文章目录
- 一、前言
- 二、简单示例
- 三、注意事项
- 四、另一种写法
- 五、拓展
- 六、参考文档
一、前言
Robolectric 是一个由 Google 维护的开源 Android 测试框架,它允许你以 Android 运行时环境运行单元测试。
Robolectric 提供了一个模拟 Android 运行时环境,允许你测试你的代码是否正确地使用 Android API。
所以在不依赖于手机的情况下可以对android项目进行测试。当然也可以在有手机的时候对Android项目进行测试
二、简单示例
以下代码源自官方文档,并进行简单完善。
文件位于src/app/test/
下面
import android.content.Intent
import android.widget.Button
import com.example.myapplication.R
import com.example.myapplication.hilt.App
import com.example.myapplication.material.MaterialTestActivity
import com.example.myapplication.roll.PaintedScrollActivity
import junit.framework.TestCase.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.Shadows.shadowOf
import org.robolectric.annotation.Config@RunWith(RobolectricTestRunner::class)
@Config(application = App::class, sdk = [28])
class RobolectricTest {// @get:Rule
// @JvmField
// val executorRule = InstantTaskExecutorRule()@Testfun clickingLogin_shouldStartLoginActivity() {Robolectric.buildActivity(MaterialTestActivity::class.java).use { controller ->controller.setup() // Moves the Activity to the RESUMED stateval activity = controller.get()activity.findViewById<Button>(R.id.button).performClick()val expectedIntent = Intent(activity, PaintedScrollActivity::class.java)val actual = shadowOf(RuntimeEnvironment.getApplication()).nextStartedActivity//新版写法使用如下方式//val actual = shadowOf(androidx.test.core.app.ApplicationProvider.getApplicationContext<App>()).nextStartedActivityprintln("YM----->,actual--> ${actual.component?.className}---->expectedIntent.name:${expectedIntent.component?.className}")assertEquals(expectedIntent.component, actual.component)}}}
这里需要注意的是需要添加
@Config(application = App::class, sdk = [28])
其中App
是应用的Application
文件。否则会有各种问题,最主要是提示不是主线程的问题。如果没有Application的话,可以使用另外一种方式。这种方式需要添加如下依赖
testImplementation "androidx.arch.core:core-testing:2.1.0"
然后添加以下代码
@get:Rule@JvmFieldval executorRule = InstantTaskExecutorRule()
不过@Config
也需要添加版本
@Config(sdk = [28])
三、注意事项
后面又经过测试,发现上述代码即使不在Config中添加App也可以运行,如
@Config(application = App::class, sdk = [28]) // X error
//改为
@Config(sdk = [28]) // 也是可以运行的
同时下面代码也没有
// @get:Rule
// @JvmField
// val executorRule = InstantTaskExecutorRule()
根据官网来说,如果不设置App的话,会自动使用程序定义的Application,但是之前代码确实一直运行失败,这里留作记录。
参考链接
四、另一种写法
这里提供另外一个测试示例,需要注意的是,其中断言可以使用以下任意一种库
testImplementation 'com.google.truth:truth:1.1.3'
testImplementation 'org.assertj:assertj-core:3.24.2'
以下是不同断言的区别:
断言库 | 适用场景 | 优势 | 适用语言 |
---|---|---|---|
JUnit Assertions | 最基础的测试 | 轻量级,适合简单测试 | Java, Android |
Google Truth | Android 开发 | 可读性好,官方推荐 | Java, Android |
AssertJ | Java 后端、复杂测试 | 功能最强大,链式断言 | Java |
Hamcrest | 传统 Java | JUnit 4 时代流行 | Java |
Kotest/Strikt | Kotlin 测试 | Kotlin DSL 语法更友好 | Kotlin |
其中使用AssertJ的话需要额外依赖Junit库
@Testfun locationListenerShouldBeUnregisteredInCreatedState() {// GIVENval controller = Robolectric.buildActivity<MaterialTestActivity>(MaterialTestActivity::class.java)controller.setup()// WHENcontroller.pause().stop()// THENassertThat(controller.get().locationListener).isNull()}@Testfun locationListenerShouldBeUnregisteredInCreatedState2() {// GIVENval scenario = ActivityScenario.launch<MaterialTestActivity>(MaterialTestActivity::class.java)// WHENscenario.moveToState(Lifecycle.State.CREATED)// THENscenario.onActivity { activity ->assertThat(activity.locationListener).isNull()}}
五、拓展
关于mock的含义,mock的作用的在测试过程中对某些功能进行模拟,保证流程能够执行下去,但是数据并不对。比如说假如自己写的一个类,需要传递Context才能保证不崩溃,那么可以使用mock进行模拟。
六、参考文档
- Robolectric 策略
- robolectric
- 构建本地单元测试
- Robolectric 4.0
- AndroidX Test
- mockito
- mockito-kotlin
相关文章:
Android中使用Robolectric测试点击事件(不需要手机)
文章目录 一、前言二、简单示例三、注意事项四、另一种写法五、拓展六、参考文档 一、前言 Robolectric 是一个由 Google 维护的开源 Android 测试框架,它允许你以 Android 运行时环境运行单元测试。 Robolectric 提供了一个模拟 Android 运行时环境,允…...
安卓开发相机功能
相机功能 安卓中的相机调用功能也经历了很多的方案升级,目前可选的官方方案是CameraX、Camera2、Camera(废弃),还有一些第三方免费或者是付费的相机库。对于大多数开发者,建议使用 CameraX。 CameraX CameraX 是 An…...
机器学习:监督学习、无监督学习和强化学习
机器学习(Machine Learning, ML)是人工智能(AI)的一个分支,它使计算机能够从数据中学习,并在没有明确编程的情况下执行任务。机器学习的核心思想是使用算法分析数据,识别模式,并做出…...

基于vue3和flask开发的前后端管理系统(一):项目启动准备
准备工作 我们需要准备以下工具 vue3:构建前端 tailwind css:样式库vite:快速构建vue项目pinia :vue3 的事件管理器 flask:后端代码Mysql:数据库 heidisql:数据库图形化界面 vscode࿱…...

一、MySQL备份恢复
一、MySQL备份恢复 1.1 MySQL日志管理 数据库中数据丢失或被破坏可能原因 误删除数据库 数据库工作时,意外断电或程序意外终止 由于病毒造成的数据库损坏或丢失 文件系统损坏后,系统进行自检操作 升级数据库时,命令语句不严格 设备故…...

DeepSeek崛起:如何在云端快速部署你的专属AI助手
在2025年春节的科技盛宴上,DeepSeek因其在AI领域的卓越表现成为焦点,其开源的推理模型DeepSeek-R1擅长处理多种复杂任务,支持多语言处理,并通过搜索引擎获取实时信息。DeepSeek因其先进的自然语言处理技术、广泛的知识库和高性价比…...
SQLite Alter 命令详解
SQLite Alter 命令详解 SQLite 是一种轻量级的数据库,广泛用于各种嵌入式系统、移动应用和小型项目。SQLite 的ALTER TABLE命令用于修改已存在的表结构,包括添加、删除或修改列,以及重命名表等操作。本文将详细解析SQLite的ALTER TABLE命令&…...

2025 聚合易支付完整版PHP网站源码
源码介绍 2025 聚合易支付完整版PHP网站源码 PHP版本:PHP74 源码上传服务器,解压访问域名即可安装 安装完成后一定要设置伪静态 源码里面nginx.txt 就是伪静态 然后复制粘贴到伪静态里面保存即可 部分截图 源码获取 2025 聚合易支付完整版PHP网站源码…...
Android开发Android调web的方法
Android开发Android调web的方法 一般都是web调Android,很少Android调web方法。 我用的是AgentWeb。它内核也是webview。 直接上代码: mAgentWeb.getJsAccessEntrace().quickCallJs("adLookSuccessAndroid",event.getType());它的意思是&am…...
FastGPT 源码:基于 LLM 实现 Rerank (含Prompt)
文章目录 基于 LLM 实现 Rerank函数定义预期输出实现说明使用建议完整 Prompt 基于 LLM 实现 Rerank 下边通过设计 Prompt 让 LLM 实现重排序的功能。 函数定义 class LLMReranker:def __init__(self, llm_client):self.llm llm_clientdef rerank(self, query: str, docume…...

字节跳动发布 Trae AI IDE!支持 DeepSeek R1 V3,AI 编程新时代来了!
3 月 3 日,字节跳动重磅发布国内首款 AI 原生集成开发环境(AI IDE)——Trae 国内版! Trae 不只是一个传统的 IDE,它深度融合 AI,搭载 doubao-1.5-pro 大模型,同时支持DeepSeek R1 & V3&…...

windows下安装Open Web UI
windows下安装openwebui有三种方式,docker,pythonnode.js,整合包. 这里我选择的是第二种,非docker. 非Docker方式安装 1. 安装Python: 下载并安装Python 3.11,建议安装路径中不要包含中文字符,并勾选“Add python 3.11 to Path”选项。 安…...

论文阅读 EEG-Inception
EEG-Inception: A Novel Deep Convolutional Neural Network for Assistive ERP-Based Brain-Computer Interfaces EEG-Inception是第一个集成Inception模块进行ERP检测的模型,它有效地结合了轻型架构中的其他结构,提高了我们方法的性能。 本研究的主要目…...
基于opencv消除图片马赛克
以下是一个基于Python的图片马赛克消除函数实现,结合了图像处理和深度学习方法。由于马赛克消除涉及复杂的图像重建任务,建议根据实际需求选择合适的方法: import cv2 import numpy as np from PIL import Imagedef remove_mosaic(image_pat…...

计算机毕业设计SpringBoot+Vue.js陕西民俗网(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
【算法方法总结·三】滑动窗口的一些技巧和注意事项
【算法方法总结三】滑动窗口的一些技巧和注意事项 【算法方法总结一】二分法的一些技巧和注意事项【算法方法总结二】双指针的一些技巧和注意事项【算法方法总结三】滑动窗口的一些技巧和注意事项 【滑动窗口】 数组的和 随着 右边指针 移动一定是 非递减 的,就是 …...

IO的概念和标准IO函数
作业: 1.使用标准IO函数,实现文件的拷贝 #include <stdio.h>int main(int argc, char *argv[]) {// 检查是否提供了源文件和目标文件if (argc ! 3) {printf("Usage: %s <source_file> <destination_file>\n", argv[0]);re…...

tauri2+typescript+vue+vite+leaflet等的简单联合使用(一)
项目目标 主要的目的是学习tauri。 流程 1、搭建项目 2、简单的在项目使用leaflet 3、打包 准备项目 环境准备 废话不多说,直接开始 需要有准备能运行Rust的环境和Node,对于Rust可以参考下面这位大佬的文章,Node不必细说。 Rust 和…...
【流程图】在 .NET (WPF 或 WinForms) 中实现流程图中的连线算法
在 .NET (WPF 或 WinForms) 中实现流程图中的连线算法,通常涉及 图形绘制 和 路径计算。常见的连线方式包括 直线、折线 和 贝塞尔曲线。以下是几种方法的介绍和示例代码。 1. 直线连接(最简单) 适用场景: 两个节点之间没有障碍…...

IDEA集成DeepSeek,通过离线安装解决无法安装Proxy AI插件问题
文章目录 引言一、安装Proxy AI1.1 在线安装Proxy AI1.2 离线安装Proxy AI 二、Proxy AI中配置DeepSeek2.1 配置本地部署的DeepSeek(Ollama方式)2.2 通过第三方服务商提供的API进行配置 三、效果测试 引言 许多开发者尝试通过安装Proxy AI等插件将AI能力…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...