记录一个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开发手册》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/929419.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第四篇:k8s 理解Service工作原理

什么是service&#xff1f; Service是将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。 简单来说K8s提供了service对象来访问pod。我们在《k8s网络模型与集群通信》中也说过k8s集群中的每一个Pod&#xff08;最小调度单位&#xff09;都有自己的IP地址&#xff0c;都…

基于ResNet50和VGG16深度学习模型的阿尔茨海默病MRI图像分类与早期诊断研究

阿尔茨海默病&#xff08;AD&#xff09;是目前全球范围内最常见的神经退行性疾病之一&#xff0c;早期诊断对延缓疾病进程和改善患者生活质量至关重要。随着医学影像学的进步&#xff0c;基于MRI图像的阿尔茨海默病检测成为一种重要的研究方向。本文提出了一种基于深度学习的M…

【日常记录-Mybatis】PageHelper导致语句截断

1. 简介 PageHelper是Mybatis-Plus中的一个插件&#xff0c;主要用于实现数据库的分页查询功能。其核心原理是将传入的页码和条数赋值给一个Page对象&#xff0c;并保存到本地线程ThreadLocal中&#xff0c;接下来&#xff0c;PageHelper会进入Mybatis的拦截器环节&#xff0c;…

MFC实现全屏功能

之前全屏都是参考&#xff1a; MFC单文档&#xff08;SDI&#xff09;全屏程序的实现 主要思路就是将各种菜单工具栏隐藏恢复。 随着MFC的升级&#xff0c;MFC框架本身就具备了全屏的功能。 微软有一个全屏实现类&#xff1a; CFullScreenImpl Class managing full-screen mod…

nn.RNN解析

以下是RNN的计算公式,t时刻的隐藏状态H(t)等于前一时刻隐藏状态H(t-1)乘以参数矩阵&#xff0c;再加t时刻的输入x(t)乘以参数矩阵&#xff0c;最后再通过激活函数&#xff0c;等到t时刻隐藏状态。 下图是输出input和初始化的隐藏状态&#xff0c;当参数batch_first True时候&…

运算符重载(五)

目录 const成员函数const对象不可以调用非const成员函数非const对象可以调用const成员函数const成员函数内不可以调用其它的非const成员函数非const成员函数内可以调用其它的const成员函 取地址及const取地址操作符重载const补充场景1场景2场景3场景4 const成员函数 将const修…

redis之RedisTemplate和StringRedisTemplate的区别

1.RedisTemplate和StringRedisTemplate的区别 StringRedisTemplate继承RedisTemplate 两者的数据是不共通的&#xff08;默认的序列化机制导致key不一样&#xff09; StringRedisTemplate默认采用的是String的序列化策略 RedisTemplate默认采用的是JDK的序列化策略&#xf…

浅探 Windows 上获取磁盘信息的几种方式(一)

获取磁盘信息是一个常见需求&#xff0c;如检查磁盘预留空间&#xff0c;开发磁盘碎片整理工具&#xff0c;系统性能优化等工具等。 Windows 为此提供了各种接口&#xff0c;今天我们主要讲讲常用相关的三个API &#xff1a; GetDiskFreeSpaceGetDiskFreeSpaceExGetDiskSpaceI…

通信综合—8.通信网络安全

一、信息系统安全概述 1.信息系统的构成和分类 信息系统是将用于收集、处理、存储和传播信息的部件组织在一起而成的相关联的整体&#xff0c;般是由计算机硬件、网络和通信设备、计算机软件、信息资源和信息用户组成。它是以处理信息流为目的的人机一体化系统。信息系统主要…

语言的艺术:探秘基于GPT模型的文本生成与优化之美

语言的艺术&#xff1a;探秘基于GPT模型的文本生成与优化之美 在人工智能蓬勃发展的今天&#xff0c;语言模型如同文字艺术的魔术师&#xff0c;赋予了计算机以“书写”的能力。基于GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型的文本生成技术&#xf…

微服务篇-深入了解 XA 模式与 AT 模式、分布式事务(部署 TC 服务、微服务集成 Seata )

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 分布式事务 1.1 认识 Seata 2.0 部署 TC 服务 2.1 准备数据库表 2.2 准备配置文件 2.3 Docker 部署 3.0 微服务集成 Seata 3.1 引入依赖 3.2 改造配置 3.3 添加数…

王道考研编程题总结

我还在完善中&#xff0c;边复习边完善&#xff08;这个只是根据我自身总结的&#xff09; 一、 线性表 1. 结构体 #define MaxSize 40 typedef struct{ElemType data[MaxSize]&#xff1b;int length; }SqList 2. 编程题 1. 删除最小值 题意 &#xff1a;从顺序表中删除…

原生html+css+ajax实现二级下拉选择的增删改及树形结构列出

<?php $db_host localhost; $db_user info_chalide; $db_pass j8c2rRr2RnA; $db_name info_chalide; /* 数据库结构SQL CREATE TABLE categories ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, parent_id INT DEFAULT 0 ); */ try { $pdo new PD…

微信小程序介绍-以及写项目流程(重要)

前言&#xff1a;本篇文章介绍微信小程序以及项目介绍&#xff1a; 文章介绍&#xff1a;介绍了微信小程序常用的指令、组件、api。tips&#xff1a;最好按照官方文档来进行学习&#xff0c;大致可以我的目录来学习&#xff0c;对于写项目是没有问题的 微信小程序官方文档https…

Data Uncertainty Learning in Face Recognition 论文阅读

Data Uncertainty Learning in Face Recognition 论文阅读 Abstract1. Introduction2. Related Work3. Methodology3.1. Preliminaries3.2. Classification-based DUL for FR3.3. Regression-based DUL for FR3.4. Discussion of Related Works 4. Experiments4.1. Datasets an…

汽车产业数字化转型:协同创新破解挑战,平衡安全与流通

在数字经济时代的浪潮中&#xff0c;数据资源和数据信息已成为驱动各行各业转型升级的“新石油”。汽车产业&#xff0c;作为国民经济的重要支柱&#xff0c;正经历着前所未有的变革。随着数字化创新和转型的深入&#xff0c;数据在汽车全产业链中的作用和价值日益凸显。在这个…

vulnhub kioptirx1.2 超详细wp

探测 nmap --min-rate 10000 -p- 192.168.128.134 最小速率10000 nmap -sT -sV -sC -O 192.168.128.134 web打点 无弱口令 暴露cms寻找exp searchsploit LotusCMS -m 16982 [输入id号和参数m可以直接把东西复制到当前目录] 查看txt里面发现 都是xss没有rce github搜索到一个…

扫二维码进小程序的指定页面

草料二维码解码器 微信开发者工具 获取二维码解码的参数->是否登陆->跳转 options.q onLoad: function (options) {// console.log("options",options.q)if (options && options.q) {// 解码二维码携带的链接信息let qrUrl decodeURIComponent(optio…

mysql基础学习1

useradd -r -g mysql -s /bin/false mysql (-r)系统用户 不能登录 A temporary password is generated for rootlocalhost: d>#jT7rfoaz) 看是否启动 看进程 端口 直接连接 看日志 varchar (20) char(20)更耗空间 create table student_info(id int,name varchar(20),s…

Echarts使用平面方法绘制三维立体柱状图表

目录 一、准备工作 1.下载引入ECharts库 2.创建容器 二、绘制基本柱状 三、绘制立体柱状方法一 1.定义立方体形状 2.注册立方体形状 3.配置custom系列 4.设置数据 5.渲染图表 四、绘制立体柱状方法二 1.画前知识 2.计算坐标renderItem 函数 &#xff08;1&#x…