当前位置: 首页 > news >正文

记录一个Flutter 3.24单元测试点击事件bug

哈喽,我是老刘

这两天发现一个Flutter 3.24版本的单元测试的一个小bug,提醒大家注意一下。
老刘自己写代码十多年了,写Flutter也6年多了,没想到前两天在一个小小的BottomNavigationBar 组件上翻了车。
给大家分享一下事件的经过。

问题经过

这件事的起因是最近想做一个自己用的小App,Flutter实现。
大家知道我一直是TDD的践行者,所以就先写了首页的测试代码。
首页底部设计有两个tab按钮,我的这个测试是点击按钮切换页面内容。
实现方法是BottomNavigationBar 配合页面内容的TabView。

结果在执行tester.tap方法的地方测试代码就崩了。
就只有一句提示
在这里插入图片描述

大家注意
No tests match “xxx…”
这种提示,如果经排查发现,测试代码中加入某个操作就出现,那么就可以怀疑一下是测试框架底层崩溃导致的。

我当时第一反应是不是我的BottomNavigationBar 的用法有问题?
因为之前是不用这个组件的,我们有自己封装的UI组件库,这次是图省事想简单看一下效果。
但是反复排查也没发现问题,而且真机运行也没问题。

这时候我还是怀疑我自己哪个地方没用对,于是把官方的组件测试代码拿过来试了一下。

testWidgets('BottomNavigationBar callback test', (WidgetTester tester) async {late int mutatedIndex;await tester.pumpWidget(MaterialApp(home: Scaffold(bottomNavigationBar: BottomNavigationBar(items: const <BottomNavigationBarItem>[BottomNavigationBarItem(icon: Icon(Icons.ac_unit),label: 'AC',),BottomNavigationBarItem(icon: Icon(Icons.access_alarm),label: 'Alarm',),],onTap: (int index) {mutatedIndex = index;},),),),);await tester.tap(find.text('Alarm'));expect(mutatedIndex, 1);
});

结果也崩了。
这时候已经是凌晨1点多了,脑子有点不清醒。
本来打算去睡觉明天再说,可是突然灵光一闪,是不是我手欠选择了Flutter 3.24.5版本的问题?
于是换成3.10,结果没问题了,测试正常通过。
然后我就清醒了,感觉问题不是出在BottomNavigationBar上,有可能所有点击事件都有问题。
于是我又写了一个简单的测试代码:

testWidgets('Button tap test', (WidgetTester tester) async {int ex = 0;await tester.pumpWidget(MaterialApp(home: Scaffold(body: Center(child: TextButton(child: const Text('Alarm'), onPressed: () {ex = 1;}),),),),);await tester.tap(find.text('Alarm'));expect(ex, 1);
});

果不其然,也崩了。
在这里插入图片描述
所以应该是Flutter 3.24版本下,test环境,点击动作有问题。

这时候凌晨两点多,已经困的不行了,睡觉,明天再说。

问题确定

第二天起来理了理思路,在想应该先排除一下我的本地环境问题,于是在我的笔记本上又尝试了一次。
笔记本也复现了这个问题,而且幸运的是笔记本上海多了一个错误提示:
在这里插入图片描述

 [ERROR:flutter/impeller/runtime_stage/runtime_stage.cc(28)] Reached unreachable code.

这个提示怎么看起来是impeler的问题呢?
上网搜了一下,果然有人报了这个bug
[ERROR:flutter/impeller/runtime_stage/runtime_stage.cc(28)] Reached unreachable code. · Issue #147551 · flutter/flutter · GitHub
而且他是在mac上,Flutter版本是3.22
我本地测试了一下Flutter 3.19,是没问题的,所以问题大概率出在3.20之后。

问题的具体细节和原因没有花时间细看。
这里一方面给大家一个提示,碰到这个问题大概知道是咋回事。
另一方面也是借着这个定位过程总结一下经验。

总结经验

1、当运行的框架,特别是框架的底层代码比如c++代码崩溃,就很容易出现一些奇怪的现象误导开发者。
比如这次的提示 【No tests match “xxx…”】
2、如果怀疑是test框架的问题,可以通过命令行运行并加入一些类似“-v”的参数查看运行更详细的过程。
这样可以帮你快速判断问题来源。
话说自己的课程里还经常提醒这一点,结果用到的时候就没想起来。
我是直到第二天用笔记本运行看到异常提示信息才想起来,这个属实有点不应该。
3、关于TDD中的UI测试,老刘一贯的观点是只测试UI中涉及业务逻辑的部分,不测试UI布局和交互的细节。
就好像这次的测试例:‘用户点击个人中心按钮,页面内容切换为个人中心’
它测试的其实是如何实现一个UI效果,这部分内容是否应该通过测试覆盖,应该覆盖到什么程度其实是值得商榷的。
比如如果我通过DefaultTabController + TabView + TabBar来实现这个效果,那其实测试的就是DefaultTabController的内部逻辑了。

好了,以上这些基于这次这个问题的思考才是我这篇文章想要表达的核心内容。
如果大家有更多的想法或者不同意见都欢迎交流。
点击免费领老刘整理的《Flutter开发手册》,覆盖90%应用开发场景。
可以作为Flutter学习的知识地图。
覆盖90%开发场景的《Flutter开发手册》

相关文章:

记录一个Flutter 3.24单元测试点击事件bug

哈喽&#xff0c;我是老刘 这两天发现一个Flutter 3.24版本的单元测试的一个小bug&#xff0c;提醒大家注意一下。 老刘自己写代码十多年了&#xff0c;写Flutter也6年多了&#xff0c;没想到前两天在一个小小的BottomNavigationBar 组件上翻了车。 给大家分享一下事件的经过。…...

使用Python将 word文档转pdf文档

第一步&#xff1a;我们需要导入支持包 >pip install pywin32 如果下载速度比较慢的话&#xff0c;可以考虑使用国内镜像源。 第二步&#xff1a;我们需要导入文件&#xff0c;这里采用 input,用户填入路径后&#xff0c;直接获取路径下的word文档&#xff0c;实现批量转换…...

基于C#+SQLite开发数据库应用的示例

SQLite数据库&#xff0c;小巧但功能强大&#xff1b;并且是基于文件型的数据库&#xff0c;驱动库就是一个dll文件&#xff0c;有些开发工具 甚至不需要带这个dll&#xff0c;比如用Delphi开发&#xff0c;用一些三方组件&#xff1b;数据库也是一个文件&#xff0c;虽然是个文…...

Vue基本语法

Options API 选项式/配置式api 需要在script中的export default一个对象对象中可以包含data、method、components等keydata是数据&#xff0c;数据必须是一个方法&#xff08;如果是对象&#xff0c;会导致多组件的时候&#xff0c;数据互相影响&#xff0c;因为对象赋值后&…...

芯片发展史

芯片的发展史可分为几个重要的阶段&#xff0c;从早期的真空管到现代的集成电路&#xff0c;反映了技术进步和创新的历程&#xff1a; 1. 真空管时代 (1904 - 1950年代) 真空管是20世纪初的电子元件&#xff0c;用于放大信号和开关&#xff0c;广泛应用在早期的收音机、电视机…...

我的知识图谱和Neo4j数据库的使用

知识图谱概述 知识图谱的含义 RDF与RDFS RDF&#xff08;Resource Description Framework&#xff0c;资源描述框架&#xff09;和RDFS&#xff08;RDF Schema&#xff0c;RDF模式&#xff09;是构建知识图谱的基础技术之一。它们提供了一种标准的方式来表示信息&#xff0c;…...

ASP.NET CORE API 解决跨域问题

环境 vs2022 .net 8 创建ASP.net Core API项目 配置跨域 编写ApiController 启动项目 得到服务器运行的 地址 在Hbuiler中创建web项目&#xff0c;编写代码 【运行】-【运行到浏览器】-选择一个浏览器,查看结果 正常显示 问题 如果允许所有源访问&#xff0c;有安全风险方…...

sram测试注意讨论

常规测试首先是mbist测试&#xff0c;原理不用多说&#xff0c;自己看&#xff0c;主要是注意点和考虑点&#xff1a; 1、明确测试用的到func_clk的频率的大小&#xff0c;根据经验值一般大于800M的时钟需要特别考虑Timing的问题&#xff1a;由于pr摆放的位置原因&#xff0c;…...

Mybatis 支持延迟加载的详细内容

延迟加载的概念深入 延迟加载是一种在处理复杂对象关系时非常有用的策略。在企业级应用开发中&#xff0c;数据库中的表之间往往存在着各种关联关系&#xff0c;如一对多&#xff08;一个用户有多个订单&#xff09;、多对多&#xff08;一个学生可以选多门课程&#xff0c;一门…...

word文档使用技巧笔记

中文和数字断开到第二行 word一串数字断开_百度知道 下划线对齐 word下划线怎么固定长度一致-百度经验...

使用docker-compose部署搜索引擎ElasticSearch6.8.10

背景 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它被广泛用于实时数据搜索、日志分析、全文检索等应用场景。 Elasticsearch 支持高效的全文搜索&#xff0c;并提供了强大的聚合功能&#xff0c;可以处理大规模的数据集并进行快速…...

bugku-web-login2

不知道为啥用bp始终登不上hackbar可以 随便输入个账号密码bp抓包&#xff0c;发现个小tip是base64加密的解密 $sql"SELECT username,password FROM admin WHERE username".$username.""; if (!empty($row) && $row[password]md5($password)){ } …...

【 AI技术赋能有限元分析与材料科学应用实践】Neo-Hookean 材料与深度学习结合的有限元分析

Neo-Hookean 材料模型是用于描述非线性弹性材料&#xff08;如软组织和橡胶等&#xff09;的经典模型&#xff0c;特别适用于大变形问题。其基本思想是通过应变能密度函数来描述材料的弹性行为。在该模型中&#xff0c;材料的应力-应变关系不仅依赖于应变能&#xff0c;还通过变…...

StarRocks关于ConcurrentModificationException 问题的解决

背景 本文基于 StarRocks 3.1.7 目前在基于Starrocks做一些数据分析的操作(主要是做一些简单的查询)&#xff0c;同事遇到了一些并发的问题: ontent:2024-11-27 07:04:34,048 WARN (starrocks-mysql-nio-pool-214933|3593819) [StmtExecutor.execute():643] execute Exceptio…...

网络安全防护指南:筑牢网络安全防线(5/10)

一、网络安全的基本概念 &#xff08;一&#xff09;网络的定义 网络是指由计算机或者其他信息终端及相关设备组成的按照一定的规则和程序对信息收集、存储、传输、交换、处理的系统。在当今数字化时代&#xff0c;网络已经成为人们生活和工作中不可或缺的一部分。它连接了世…...

替代FTP最佳跨网文件传输解决方案——FileLink

在传统的企业文件传输中&#xff0c;FTP&#xff08;文件传输协议&#xff09;曾因其便捷性和高效性被广泛应用。然而&#xff0c;其固有的安全漏洞、对大文件传输支持的局限性、易受网络攻击等问题&#xff0c;已逐渐暴露出FTP在现代企业环境下的不足。针对这一问题&#xff0…...

Cesium在vue2中的引入和注意事项

在Vue2中&#xff0c;可以使用npm包管理工具来安装Cesium&#xff0c;并通过import语句将其引入到项目中。下面是在Vue2中引入Cesium的步骤和注意事项&#xff1a; 步骤&#xff1a; 首先&#xff0c;打开终端并进入Vue项目的根目录。 运行以下命令来安装Cesium&#xff1a; …...

CentOS 9 配置静态IP

文章目录 1_问题原因2_nmcli 配置静态IP3_使用配置文件固定IP4_重启后存在的问题5_nmcli 补充 1_问题原因 CentOS 7 于 2014年6月发布&#xff0c;基于 RHEL 7&#xff0c;并在 2024年6月30日 结束维护。 CentOS 9 作为目前的最新版本&#xff0c;今天闲来闲来无事下载下来后…...

深入解析 Webhook:从原理到实践的全面指南

1. 引言 1.1 什么是 Webhook&#xff1f; Webhook 是一种基于 HTTP 回调的轻量级通信机制&#xff0c;它允许一个系统实时向另一个系统发送数据。当特定事件发生时&#xff0c;Webhook 会主动向指定的 URL 发送 HTTP 请求&#xff0c;通常携带事件相关的数据。这种被动接收通…...

基于springboot+vue实现的创新创业学分管理系统 (源码+L文+ppt)4-111

4 系统总体设计 4.1系统功能结构设计图 根据需求说明设计系统各功能模块。采用模块化设计方法实现一个复杂结构进行简化&#xff0c;分成一个个小的容易解决的板块&#xff0c;然后再将小的板块继续分化成功能单一的更小模块。模块化设计方法使测试调试、维护更容易&#xff…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...