首页/新闻资讯/正文详情

Flutter Engine Android Java 单元测试实战指南:基于 Robolectric 与 JUnit 4 的完整测试方案

发布时间:2026/9/28 3:05:33 来源:云帆数科 栏目:资讯中心
Flutter Engine Android Java 单元测试实战指南:基于 Robolectric 与 JUnit 4 的完整测试方案
跨平台图形学前端【免费下载链接】engineThe Flutter engine项目地址https://gitcode.com/gh_mirrors/eng/engine点击查看免费下载本文聚焦 Flutter Engine 仓库中 Android 平台 Java 代码的单元测试体系它基于 Robolectric当前仓库 test_runner/build.gradle 实际采用 4.14.1文档要求的基线为 4.12.1与 JUnit 4让引擎的 Android embedding 代码无需真机即可在 JVM 上完成验证。读完本文你将掌握新增一个 Java 测试类的完整流程、如何构建引擎并通过 testing/run_tests.py 单独运行某个测试类以及三类高频问题类找不到、import 编译失败、日志不输出的排查方法。测试体系概览为什么用 RobolectricFlutter Engine 的 Android 侧代码位于shell/platform/android/java/覆盖 embedding、plugin、util、view 等包此前长期缺少单元测试——shell/platform/android/test/README.md 明确说明测试套件是在绝大部分 Java 代码写完之后才补充的因此多数历史类仍没有测试覆盖。文档确立的规范是此后的新代码应当被测试要么在本仓库通过单元测试覆盖要么在框架仓库通过集成测试覆盖。这套单元测试的技术选型有两个关键约束Robolectric在 JVM 上模拟 Android SDK无需模拟器或真机可以实例化Activity、View、Resources等真实 Android 对象JUnit 4与 Robolectric 搭配的经典测试运行器。仓库中几乎所有测试类都用RunWith(AndroidJUnit4.class)注解例如 FlutterViewTest.java、AndroidTouchProcessorTest.java少数场景直接使用RunWith(RobolectricTestRunner.class)例如 LogTest.java 与 FlutterEngineGroupCacheTest.java。AndroidJUnit4是 androidx.test 对 Robolectric 的扩展封装与 Robolectric 完全兼容。测试目录结构与命名约定所有测试文件统一放在shell/platform/android/test/目录下并镜像被测试类的包路径与类名目录镜像包结构shell/platform/android/java/io/flutter/util/Preconditions.java对应shell/platform/android/test/io/flutter/util/PreconditionsTest.java类名规则被测试类名 Test后缀。从当前仓库的实际目录看该约定已被严格贯彻shell/platform/android/test/io/flutter/下按embedding/android、embedding/engine、plugin/editing、plugin/platform、util、view等包分层组织共 80 余个测试类。这种测试与被测类同包同名的做法带来的直接收益是测试代码可以访问包级可见的成员与方法无需为测试额外暴露 public API。新增一个 Java 测试的完整步骤第一步创建测试文件在shell/platform/android/test/下按镜像规则创建文件例如为io.flutter.util.Preconditions创建shell/platform/android/test/io/flutter/util/PreconditionsTest.java。第二步注册到 GN 构建目标将新文件加入 shell/platform/android/BUILD.gn 中robolectric_tests目标的sources使其被编译进测试 jar。需要注意当前仓库的一个现状shell/platform/android/BUILD.gn第 612 行处的group(robolectric_tests)目前只是一个占位目标deps [:android_jar]真正的测试编译与执行由下述 Gradle 工程负责但从规范层面看robolectric_tests仍是测试文件的登记处README 亦明确要求把新测试类加入其sources。第三步注册到测试套件在 README 描述的方案中新测试类需要被 import 并加入FlutterTestSuite.java的SuiteClasses注解从而保证测试在运行时真正被执行。需要说明的是当前仓库中尚未检索到FlutterTestSuite.java文件本身说明该套件类以及SuiteClasses汇总机制属于文档描述的演进方案而当前仓库的实际执行路径已迁移到 Gradle 的testDebugUnitTest任务见下文运行机制。如果读者所在分支保留了该套件文件请按第 3 步操作否则以 Gradle 任务为最终执行入口。第四步编写测试参照仓库中既有测试的写法典型的测试骨架如下节选自 SmokeTest.java该测试用于验证 Robolectric 能正常加载并 mock Android APIpackage io.flutter; import static org.junit.Assert.assertTrue; import android.text.TextUtils; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; /** Basic smoke test verifying that Robolectric is loaded and mocking out Android APIs. */ Config(manifest Config.NONE) RunWith(AndroidJUnit4.class) public class SmokeTest { Test public void androidLibraryLoaded() { assertTrue(TextUtils.equals(xyzzy, xyzzy)); } }要点说明RunWith(AndroidJUnit4.class)接入 Robolectric 运行环境Config(manifest Config.NONE)表示不加载 manifest适合不依赖 Android 资源的纯逻辑测试需要 Android 资源如主题、drawable的测试可配合RobolectricFlutterActivity、SplashShadowResources等仓库内置的测试支撑类位于shell/platform/android/test/io/flutter/embedding/android/涉及交互对象的测试常用 Mockito仓库在 test_runner/build.gradle 中固定了mockito-core、mockito-inline、mockito-android三个 4.7.0 依赖FlutterViewTest.java 中大量mock/spy/when/verify用法可直接参考。第五步构建并运行# 1. 先构建引擎产物run_tests.py 不负责构建引擎 et build -c android_debug_unopt_arm64 # 2. 运行 Java 单元测试可加 --java-filter 只跑指定类 testing/run_tests.py --android-variantandroid_debug_unopt_arm64 \ --typejava \ --java-filterio.flutter.embedding.android.FlutterViewTest原文档中的 Mac 示例即为此命令形态。注意 testing/run_tests.py不会构建引擎二进制引擎必须预先构建当引擎源码发生变化时也需要重新构建。引擎的完整编译方法可参考仓库内的 docs/contributing/Compiling-the-engine.md 与 docs/contributing/Setting-up-the-Engine-development-environment.md。运行机制run_tests.py 背后发生了什么testing/run_tests.py的run_java_tests()函数testing/run_tests.py揭示了整套 Java 测试的执行链路它定位到shell/platform/android/test_runner目录下的 Gradle 工程使用仓库自带的third_party/gradle/bin/gradleWindows 为gradle.bat执行testDebugUnitTest任务通过-Pflutter_jarout/variant/flutter.jar把刚构建好的引擎 jar 作为被测对象喂给 Gradle通过--teststest_class精确过滤要运行的测试类未指定时用*匹配全部附加--rerun-tasks强制重跑、--no-daemon、独立的--project-cache-dir与--gradle-user-home保证每次执行环境干净可复现环境变量注入ANDROID_HOME指向仓库自带 SDKthird_party/android_tools/sdk与JAVA_HOME。Gradle 工程本身在 test_runner/build.gradle 中配置sourceSets把../test目录设为测试源码目录即上面创建的测试文件会自动纳入编译测试依赖包括org.robolectric:robolectric:4.14.1、junit:junit:4.13.2、androidx.test:core:1.4.0、com.google.android.play:core、icu4j以及 Mockito 全家桶。测试运行参数也在此定义单测 JVM 堆上限-Xmx8g、按 CPU 数并行分叉、testLogging输出 passed/skipped/failed 与标准输出/错误流。两个值得注意的细节依赖版本以当前仓库为准README 写的是 Robolectric 4.12.1而 test_runner/build.gradle 当前锁定 4.14.1、JUnit 4.13.2说明测试基础设施已随仓库演进升级嵌入依赖单独管理test_runner/build.gradle 中的注释明确要求不要把 embedding 依赖加进本文件嵌入依赖统一由tools/androidx/files.json与 tools/androidx/configure.gradle 管理。常见问题排查QAQ1新测试无法运行抛出 ClassNotFoundException说明测试运行时缺少某个类。根因通常是嵌入依赖embedding dependencies未更新或未同步——这些依赖以 CIPD 包的形式随引擎 checkout 提供。解决步骤见 tools/cipd/android_embedding_bundle/README.md修改tools/androidx/files.json其中包含了构建 Flutter 应用所需的 Maven 依赖清单除 androidx 外还含 ReLinker 等非 androidx 依赖在tools/cipd/android_embedding_bundle目录下依次执行gradle downloadLicenses与gradle updateDependencies重新生成依赖包将生成的lib/目录同步到third_party/android_embedding_dependencies/并用cipd create --pkg-def cipd.yaml发布新版本 CIPD 包更新 DEPS 中的android_embedding_dependenciestag最后同步更新 shell/platform/android/BUILD.gn 中的embedding_dependencies_jars列表。该流程的实质是引擎自身的构建依赖与测试依赖都由此 CIPD 包统一供给依赖漂移会同时导致编译期与运行期的符号缺失。Q2新测试编译失败找不到 import与 Q1 同源import 的类来自嵌入依赖包而该包版本过旧。同样按照 tools/cipd/android_embedding_bundle/README.md 更新嵌入依赖后重新构建即可。此外需检查是否误把 embedding 依赖写进了 test_runner/build.gradle 的dependencies块——该文件的注释明确禁止这样做测试类能且只能通过configureDependencies读取tools/androidx/files.json获得嵌入依赖。Q3测试没有在控制台输出日志Robolectric 默认把日志吞掉需要在测试类中显式接通日志流。在测试类或Before设置方法中写入import org.robolectric.shadows.ShadowLog; ShadowLog.stream System.out;这是 README 给出的标准做法。仓库中的 FlutterEngineTest.java 还演示了另一种进阶用法通过ShadowLog.getLogsForTag(GeneratedPluginsRegister)按 tag 抓取 Robolectric 捕获的日志条目并对其断言例如检查其中的异常 cause适合做日志行为的自动化验证。测试编写进阶从仓库测试中可借鉴的模式当前shell/platform/android/test/下已有大量可直接借鉴的测试样本按主题分类平台通道验证embedding/engine/systemchannels/下的AccessibilityChannelTest、TextInputChannelTest、PlatformChannelTest、KeyboardChannelTest等覆盖 Flutter 与 Android 平台通道的编解码与消息分发插件机制plugin/common/MethodChannelTest、StandardMessageCodecTest、BinaryCodecTest、plugin/editing/TextInputPluginTest、plugin/platform/PlatformViewsControllerTest、PlatformViewWrapperTest等视图与生命周期embedding/android/下的FlutterViewTest、FlutterActivityTest、FlutterFragmentTest、FlutterSurfaceViewTest、FlutterTextureViewTest等用于验证 embedding 层对 Activity/Fragment/View 生命周期的响应引擎基础设施FlutterEngineTest、FlutterJNITest、FlutterShellArgsTest、DartExecutorTest、DartMessengerTest等。这些测试共同依赖仓库内置的测试支撑设施FlutterEngineRuleRobolectric 环境下的 FlutterEngine 生命周期管理、RobolectricFlutterActivity、SplashShadowResources、CustomShadowContextImpl、FakeKeyEvent/KeyCodes等均位于shell/platform/android/test/io/flutter/对应包下新增测试时可优先复用避免重复造轮子。小结Flutter Engine 的 Android Java 单元测试方案以 Robolectric JUnit 4 为核心通过测试目录镜像包结构、GN/Gradle 双轨构建、run_tests.py 统一调度的方式为 embedding、插件、平台通道等核心 Java 代码提供了低成本、可重复的回归保障。新增测试时遵循五步流程建文件 → 登记robolectric_tests的 sources → 挂入测试套件 → 编写用例 → 构建后运行并牢记两条铁律引擎必须先构建再跑测试、嵌入依赖必须经由tools/androidx/files.json CIPD 包统一更新即可把绝大多数踩坑点挡在门外。赞分享跨平台图形学前端【免费下载链接】engineThe Flutter engine项目地址https://gitcode.com/gh_mirrors/eng/engine点击查看免费下载相关推荐抖音批量下载完整指南快速一次保存视频和音乐抖音批量下载完整指南快速一次保存视频和音乐 想把某个抖音创作者的作品批量存到本地时Douyin Downloader 可以一步完成粘贴主页链接视频、背景网页爬虫CLIRealm Java 单元测试实战指南基于 unitTestExample 的 Robolectric、PowerMock 与 Espresso 三层测试方案Realm Java 单元测试实战指南基于 unitTestExample 的 Robolectric、PowerMock 与 Espresso 三层测试方案数据库移动开发嵌入式数据库OpCore Simplify终极指南15分钟智能搞定黑苹果EFI配置OpCore Simplify终极指南15分钟智能搞定黑苹果EFI配置 OpCore Simplify是一款革命性的黑苹果配置工具专为简化OpenCore开发工具CLI上一篇如何通过League Akari实现英雄联盟效率革命从新手到高手的进阶指南下一篇为 Akka Persistence Durable State 构建存储后端插件从接口实现到配置激活的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

Dendron 工作区根笔记(root.md)完全指南:结构、生命周期与发布语义
Dendron 工作区根笔记(root.md)完全指南:结构、生命周期与发布语义

知识管理知识库 【免费下载链接】dendron The personal knowledge management (PKM) tool that grows as you do! 项目地址: https://gitcode.com/gh_mirrors/de/dendron 点击查看 免费下载 导读 本文以 test-workspace/assets/root.md 这份仓库中的真实根笔记为线… · 2026/9/28 3:05:33

北京大兴企业网站建设哪家好避坑指南设计师转前端必看
北京大兴企业网站建设哪家好避坑指南设计师转前端必看

北京大兴企业网站建设哪家好避坑指南设计师转前端必看 很多设计师刚转行做前端,或者自己手里有客户资源,想接点建站单,心里最慌的就是这行:自己不会代码,怎么给客户交付一个像样的网站?这时候满大街搜“北京大兴企业网站建设哪家好”,看着眼花缭乱,其… · 2026/9/28 3:05:26

侵入式设计
侵入式设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/28 3:05:26

Spingboot启动预热的实现
Spingboot启动预热的实现

启动预热的适用场景启动预热适合以下情况:数据主要来自第三方接口,无法直接从本地数据库读取。第三方接口响应较慢,首次访问容易超时。一个页面需要调用多个第三方接口或逐项查询。数据读取频繁,但变化不频繁。希望服务启动后&… · 2026/9/28 3:40:12

Understanding Driving Risks using Large Language Models: Toward Elderly Driver Assessment
Understanding Driving Risks using Large Language Models: Toward Elderly Driver Assessment

文章主要内容总结 本文研究了多模态大语言模型(具体为ChatGPT-4o)利用静态行车记录仪图像进行类人交通场景解读的潜力,重点聚焦与老年司机评估相关的三项任务:交通密度评估、交叉口可见性评估和停车标志识别。这些任务需上下文推理而非简单目标检测。研究采用零样本、少样… · 2026/9/28 3:32:43

Leveraging Large Language Models for Classifying App Users‘ Feedback
Leveraging Large Language Models for Classifying App Users‘ Feedback

文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)解决应用用户反馈分类的挑战,传统方法依赖有监督机器学习,但受限于标注数据集的规模和质量。研究通过三个核心实验评估了4种先进LLMs(GPT-3.5-Turbo、GPT-4o、Flan-T5、Llama3-70b)的性能: LLMs在用户反馈分类中的基… · 2026/9/28 3:32:43

Using Large Language Models for Legal Decision-Making in Austrian Value-Added Tax Law: An Experim...
Using Large Language Models for Legal Decision-Making in Austrian Value-Added Tax Law: An Experim...

文章主要内容总结 本文通过实验评估了大型语言模型(LLMs)在奥地利及欧盟增值税(VAT)法框架下辅助法律决策的能力。研究聚焦于两种提升LLM性能的方法——微调(fine-tuning)和检索增强生成(RAG),并在两类案例中进行验证:一是权威教科书案例,二是税务咨询公司的真实案… · 2026/9/28 3:32:43

学Java别走弯路,这5个方向最吃香
学Java别走弯路,这5个方向最吃香

学Java的人很多,但学明白的人不多。有人学了半年还在写控制台程序,有人一年就能独当一面。差别不在天赋,而在方向。Java生态太庞大了,什么都学等于什么都没学。选对方向,事半功倍。今天盘点当前最吃香的5个Java方向&am… · 2026/9/28 3:32:15

AlphaAgents: Large Language Model based Multi-Agents for Equity Portfolio Constructions
AlphaAgents: Large Language Model based Multi-Agents for Equity Portfolio Constructions

AlphaAgents相关总结与翻译 一、文章主要内容总结 (一)研究背景与问题 传统股票投资组合管理依赖人类分析师处理海量信息(如财务披露、财报、市场新闻等),存在信息处理效率低、易受认知偏差(如损失厌恶、过度自信)影响的问题,可能错失投资收益机会。尽管AI在数据处理… · 2026/9/28 3:32:08

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

制作网页比较方便的软件怎么选?一文搞懂避坑指南
制作网页比较方便的软件怎么选?一文搞懂避坑指南

制作网页比较方便的软件怎么选?一文搞懂避坑指南 很多老板一上来就问:做个网站多少钱?但我反问他:你的域名买了吗?服务器租了吗?他一脸懵。这就是典型的“域名服务器搞不懂”。别急,今天咱们不聊虚的,直接 一文搞懂 那些让你头秃的技术名词。… · 2026/9/28 0:00:06

婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量
婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量

婚恋网站实战案例:避开3个高价坑,省钱50%还能跑赢流量 找婚恋网站建站公司,最怕的就是被坑高价。很多同行跟我吐槽,报价单上写得模棱两可,功能栏里全是“高级定制”、“专属UI”,结果落地全是套壳。今天不聊虚的,直接甩几个我经手的 实战案例… · 2026/9/28 0:00:19

济南做网站多少钱:3个案例拆解,防黑源码下载全攻略
济南做网站多少钱:3个案例拆解,防黑源码下载全攻略

济南做网站多少钱:3个案例拆解,防黑源码下载全攻略 上周济南一个做建材的老板找我,脸都绿了。他的官网首页弹出了赌博广告,后台被植入了挖矿脚本。他慌得问我:“网站被黑挂马不知道怎么办?能不能直接找之前的外包公司要源码下载,看看哪里被动了手脚?… · 2026/9/28 0:00:25

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码