软件测试线上问题已经解决,这就完事了?

Posted 程序员小濠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件测试线上问题已经解决,这就完事了?相关的知识,希望对你有一定的参考价值。

1. 前言

作为一名自信的 QA,对于测试通过的项目,如果有人反馈有问题,脑海中的第一反应一定就是:不可能!一定是操作有问题。入职以来经手大大小小的项目也有 40 多个,一直没出过问题,也让我在年度的总结上自信地写到:所有项目按时按质发版,未出现线上问题。

但是,这种自信让我掉以轻心,使得微信小程序 SDK 的第一个线上问题也随之而来了。

对于线上问题,可能很多人都以为把问题解决了就完事了,并不重视对问题的复盘。事实上,复盘的作用可能远大于解决问题本身。

在神策的企业文化中重要的一项就是复盘,每一个问题对于我们来说都是一笔宝贵的财富。通过对于问题的复盘,总结经验教训,能够更好地促进我们成长。

下面我们来看下对于这个问题是如何进行复盘的。

2. 回顾目标

神策微信小程序 SDK 的目标是实现对于主流小程序开发框架的全埋点功能。但是,在测试过程中发现由于 Taro3.0 框架重新定义了标签点击行为的逻辑,使得一次点击行为会触发 SDK 的两次点击事件 $MPClick,造成了埋点数据重复。

因此,这次发布的 v1.14.3 版本旨在解决 Taro3.0 框架下点击事件重复触发的问题,实现神策微信小程序 SDK 真正意义上的无框架障碍全埋点采集。

3. 评估结果

3.1. 符合目标

  • 解决了 Taro3.0 框架下点击事件重复触发的问题;
  • 实现了神策微信小程序 SDK 真正意义上的无框架障碍全埋点采集。

3.2. 低于目标

  • 本次发布的版本存在严重的线上问题。

4. 分析原因

4.1. 回顾过程

  1. 2020 年 12 月 17 日 19 : 05 微信小程序 SDK 发布了 v1.14.3 版本,新增了 $MPClick 事件可自定义属性,修复了 Taro3.0 框架下点击事件重复触发的问题;
  2. 2020 年 12 月 18 日 16 : 27 技术顾问收到客户反馈:微信小程序 SDK 更新到 v1.14.3 版本后,测试过程中发现 SDK 篡改了他们方法的返回值,属于破坏型 proxy;
  3. 2020 年 12 月 18 日 16 : 30 技术顾问查看代码发现这个问题以前在支付宝小程序出现过,并和 QA 一起复现了问题;
  4. 2020 年 12 月 18 日 16 : 35 问题同步给研发和 QA 组长,并分配下一步具体工作:QA 去 GitHub 上删除对应版本代码,研发组长协助删除 npm 上的版本,研发开始修复问题;
  5. 2020 年 12 月 18 日 16 : 37 研发组长和 QA 完成版本删除;
  6. 2020 年 12 月 18 日 16 : 45 研发修复完成,交由 QA 测试;
  7. 2020 年 12 月 18 日 18 : 05 QA 测试完成,并发布了最新的修复版本 v1.14.4,完成了线上验证;
  8. 2020 年 12 月 19 日 11 : 31 技术顾问组长找出了所有使用问题版本 v1.14.3 的客户并同步给技术顾问;
  9. 2020 年 12 月 19 日 15 : 00 技术顾问通知了所有使用 v1.14.3 的客户,告知他们存在的问题并提醒他们更新版本。

整个问题的生命周期从 2020 年 12 月 17 日 19 : 05 发版,到 2020 年 12 月 19 日 15 : 00 所有客户通知完成,总共历时 44 个小时。可以分为如图 4-1 中的 6 个阶段:

图 4-1 线上问题生命周期

这次问题是我经历的第一个线上问题,这次经历不仅让我完整了解到线上问题的处理流程,更让我充分地感受到各个环节上团队人员的密切配合。从问题开始到问题解决,小程序团队全员时刻处于待命状态,每个环节都争分夺秒,确保了此次问题的快速修复,没有造成较大的影响。

回顾线上问题的整个过程之后,我们需要分析产生这个问题的具体原因。

4.2. 原因分析

4.2.1. 自动采集点击事件

在进行具体的原因分析之前,我们先来看下神策微信小程序 SDK 自动采集点击事件的原理。

1、在重写 Page 函数时,先通过 _.getMethods 获取除 Page 钩子以外的自定义事件处理函数集合 methods:

Page = function (option) {    // 先判断 mpClick 是否配置自动采集,若配置为真则获取自定义方法并代理重写    var methods = sa.para.autoTrack && sa.para.autoTrack.mpClick && _.getMethods(option);     if(!!methods) {      for(var i = 0, len = methods.length; i < len; i++) {        // 对 methods 集合的每一个自定义事件处理函数进行重写        click_proxy(option, methods[i]);      }    }}// _.getMethods 方法,获取用户自定义的所有事件 _.getMethods = function(option) {  var methods = [];  for (var m in option) {    if (typeof(option[m])==='function' && !mpHook[m]) {      methods.push(m);    }  }  return methods;}
复制代码

2、对 methods 集合的每一个自定义事件处理函数进行重写,获取事件触发时的 type 类型,type 为 tap、longpress 或者 longtap 则触发 $MPClick 事件,将 wxml 文件标签中 dataset 定义的属性作为事件属性:

// 点击事件代理处理函数  function click_proxy(option, method) {    var oldFunc = option[method];        option[method] = function() {      // 在重写 oldFunc 之前就已经判断是一个方法类型,此处是做一次重复的校验      var res = oldFunc.apply(this, arguments);       var prop = {},          type = '';       if(_.isObject(arguments[0])) {        // 将 wxml 标签中 dataset 定义的属性作为事件属性        var dataset = current_target.dataset || {};        type = arguments[0]['type'];        prop['$element_id'] = current_target.id;        prop['$element_type'] = dataset['type'];        prop['$element_content'] = dataset['content'];        prop['$element_name'] = dataset['name'];      }      if(type && _.isClick(type)) {        prop['$url_path'] = _.getCurrentPath();        sa.track('$MPClick', prop);      }      return res;    }  }; // 点击类型判断方法_.isClick = function(type) {  var mpTaps = {    "tap": 1,    "longpress": 1,    "longtap": 1,  };  return !!mpTaps[type];}
复制代码

点击事件的自动采集不仅能采集到用户的点击行为,还能自动采集点击标签的相关属性。

只要在 wxml 文件的标签中通过 data- 定义的属性都可以采集到,可以自动采集的属性如表 4-1 所示:

表 4-1 自动采集的属性

建议在元素中定义 id 、data-content、data-name 这三个元素之一作为元素标识,若无这三个属性,则在神策分析平台无法进行标识。

接下来,我们来看一个自动采集点击事件的例子。

1、配置如下的 button 标签:

<button bindtap="test" data-name="button" id="button" data-content='button' data-type="button">测试</button>
复制代码

2、点击 button 后触发的事件内容如下所示:

{"distinct_id":"1610349175397-726909-0e567a51188708-20891891""lib":{"$lib":"MiniProgram""$lib_method":"code""$lib_version":"1.14.4"}"properties":{"$lib":"MiniProgram""$lib_version":"1.14.4""$network_type":"wifi""$manufacturer":"devtools""$model":"iPhone 6/7/8 Plus""$screen_width":414"$screen_height":736"$os":"devtools""$os_version":"10.0.1""$timezone_offset":-480"$app_id":"wx82a49f7cb5547449""$url_path":"pages/index/index""$element_id":"button""$element_type":"button""$element_content":"button""$element_name":"button""$is_first_day":false"$ip":"117.71.111.48""$browser":"WeChat""$browser_version":"7.0.4""$is_login_id":false"$city":"合肥""$province":"安徽""$country":"中国"}"anonymous_id":"1610349175397-726909-0e567a51188708-20891891""type":"track""event":"$MPClick""time":1615194119222"is_login_id":false"map_id":"1610349175397-726909-0e567a51188708-20891891""user_id":-8183290914376425000"recv_time":1615194119222"project":"gongcheng"}
复制代码

至此,我们可以看到自动采集了 button 的点击事件。

4.2.2. 具体原因

了解了微信小程序 SDK 是如何实现自动采集点击事件的原理,此次问题的原因就比较容易分析了,下面我们看下导致此次问题的具体原因是什么。

1、首先我们需要了解下小程序的页面逻辑,每个页面都有一个单独的 JS 文件为页面组件添加执行逻辑,所有方法都写在 Page( { } ) 中,主要包含三个部分:页面的初始数据,小程序本身带有的生命周期函数和自定义的函数方法。例如下面示例中定义的两个方法 testA 和 testB:

Page({   /**   * 页面的初始数据   */  data: {   },   /**   * 生命周期函数--监听页面加载   */  onLoad: function (options) {      },   /**   * 自定义方法 testA   */  testA: function () {   console.log('执行方法 B',this.B())  },     /**   * 自定义方法 testB   */  testB: function () {   return '执行方法 B'  }})
复制代码

2、根据上一节提到的点击事件自动采集原理,我们对客户小程序的所有自定义方法进行了重写代理,判断 type 类型为点击时触发 $MPClick 事件,但前提一定是不能影响客户自定义方法的执行; 

3、小程序 SDK v1.14.3 版本在更新现有逻辑时,修改了代理方法的返回值,由返回客户方法的执行结果改成了直接返回 false,如图 4-2 所示:

图 4-2 小程序 SDK v1.14.3 版本代码 diff 图

4. 这就使得上面代码中 Page 自定义的方法 testB(),原本客户业务逻辑是 “return '执行方法 B'”,但是经过我们 SDK 的方法重写,变成了 “return false”。

5. testA() 本来应该打印出 testB() 中定义的返回值,不过由于 SDK 代理使得 testB() 返回 false,导致 testA() 的执行结果不符合预期,如图 4-3 所示:

图 4-3 testA() 的错误执行结果

正确的业务逻辑执行结果应该如图 4-4 所示:

4.2.3. 解决方案

知道了问题的原因之后,解决问题就比较容易了。只需要在代理客户方法时修改返回值为客户原来方法的返回值,如图 4-5 所示:

5. 总结规律

5.1. 经验教训

虽然此次线上问题的原因比较简单,但是经过深刻的反省之后,我总结了如下几点经验教训:

  1. QA 对代码的改动需要具有敏锐的感知,要详尽追究每行代码改动的目的。对于代码的 diff,一定要知其然,知其所以然。QA 可能不需要编写很复杂的代码,但是一定要能看懂代码,否则测试覆盖率一定不高;
  2. 此次问题的发生主要在于 QA 的测试 case 未覆盖到方法的返回值,对于小程序基本原理理解的不够深入。因此,QA 需要对测试的业务非常熟悉,通过业务属性探索测试 case;
  3. QA 没有遵守流程,在研发组长没有给出 code review 通过的回复之前,就直接开始测试。这样使得测试代码是未经过 double check 的,很容易出现问题;
  4. 此次问题属于再犯,之前在其他小程序上也出现过同样的问题。这种再犯的问题是最可怕的,表明了没有对出现的问题做好总结。对于 QA 而言,需要将漏测的 case 加入回归测试的 case 中,定期对回归测试的 case 进行总结。

5.2. 问题

通过此次线上问题暴露了自己作为一名 QA 所存在的一些问题:

  1. 对于 SDK 代码和小程序基本原理还不够熟悉;
  2. 对于代码的改动没有追根究底,相关逻辑的了解不够充分;
  3. 没有严格遵守测试流程;
  4. 没有及时总结已有的问题,导致同样的问题再次出现。

5.3. 改进

经过此次线上问题的复盘,有如下行动作为改进的方向:

  1. QA 在 2021 年的 Q1 季度完成对微信小程序 SDK 代码的熟读,研发负责组织 2 次以上针对 QA 的小程序基本原理培训,从而让 QA 和研发在代码理解上达到水平一致;
  2. 研发在以后项目中需要详细评估改动,准确定位影响范围,并在相应的提测邮件上重点备注,让 QA 能更详尽的设计测试 case;
  3. 此次问题之后,QA 和研发都需要严格遵守开发测试流程,相互监督,绝不在任何一个流程环节中出现越界或者违规;
  4. QA 在 2020 年 12 月底之前完成对此次问题的详细总结,并把漏测的 case 加入到回归测试 case 中,防止再次出现同样的问题。本文通过对于一次线上问题的复盘,介绍了复盘的整体流程,希望通过本文能给大家提供一些复盘相关的参考。

下面有我整理的一些软件测试资料有兴趣可以一起学习最后祝大家 前程似锦!!

å¨è¿éæå¥å¾çæè¿°

一、测试基础
了解测试的基础技能,掌握主流缺陷管理工具的使用,熟练测试环境的操作与运维

å¨è¿éæå¥å¾çæè¿°

二、Linux必备知识
Linux作为现在最流行的软件环境系统,一定需要掌握,目前的招聘要求都需要有Linux能力。

å¨è¿éæå¥å¾çæè¿°
三、Shell脚本
掌握Shell脚本:包括Shell基础与运用、Shell逻辑控制、Shell逻辑函数

å¨è¿éæå¥å¾çæè¿°
四、互联网程序原理
自动化必经之路:前端开发基础知识以及互联网网络必备知识四、互联网程序原理

å¨è¿éæå¥å¾çæè¿°
五、mysql数据库
软件测试工程师必备MySQL数据库知识,不仅仅停留在基本的“增删改查”。

å¨è¿éæå¥å¾çæè¿°

六、抓包工具
Fiddler,Wireshark,Sniffer,Tcpdump各种抓包工具适用于各种项目,总有一款适合你的

å¨è¿éæå¥å¾çæè¿°

七、接口测试工具
接口测试神器,你绕不开的强大工具:Jmeter。小巧灵活:Postman

å¨è¿éæå¥å¾çæè¿°
八、Web自动化测试Java&Python
了解自动化的目的,熟练掌握TestNG&unittest自动化框架,以及断言与日志处理

å¨è¿éæå¥å¾çæè¿°
九、接口与移动端自动化
专业接口调用、测试解决方案。组建完整的web和接口自动化框架,Appium整体使用

å¨è¿éæå¥å¾çæè¿°
十、敏捷测试&TestOps构建
揭开TestOps的神秘面纱,持续集成Jenkins框架烂熟于心

å¨è¿éæå¥å¾çæè¿°

十一、性能测试&安全测试
软件测试的彼岸:性能测试和安全测试,选个方向努力爬坑吧!

å¨è¿éæå¥å¾çæè¿°
最后:【可能给予你帮助】然后下面分享一些我的自学资料,希望可以帮到大家。

这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。

关注我的微信公众号:【 程序员小濠】免费获取~

加群:175317069,群里有测试大牛分享经验。

最后感谢相遇,感谢缘分,感谢支持,感谢选择,感谢信任。也祝大家可以顺利找到心仪的工作,成功转行软件测试工程师!拿下高薪!

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

 

好文推荐:

6个月软件测试培训出来后的感悟--写给正在迷茫是否要转行或去学软件测试的学弟学妹们!

看破世态炎凉!吾儿大帝之姿30岁转行学习软件测试拿到13k+

27岁转行软件测试——那年毕业,不知换了多少工作....

27岁只会“功能测试“(点点点),面临公司的“淘汰”?沉淀一年我能继续做测试!

以上是关于软件测试线上问题已经解决,这就完事了?的主要内容,如果未能解决你的问题,请参考以下文章

学Java看这就完事了!java本地上传文件到服务器

学Java看这就完事了!java最新版本官网网址

学Java看这就完事了!java项目变成web项目

sublime代码片段功能

不改一行代码定位线上性能问题

不改一行代码定位线上性能问题