BUG,带给我的思考

时间:2022-04-27 02:35:53

今天打开EverNote时,翻到了四年前在anjuke时做的一些bug分析总结。现在回过头看看也是有些价值所在,挑选出部分bug分享,希望能有所启发。

一、

iOS新房APP4.4由于在91市场进行试点时,量大的crash召回。具体情况如下:

*** -[__NSArrayM objectAtIndex:]: index 20 beyond bounds [0 .. 19]

*** -[__NSArrayM objectAtIndex:]: index 40 beyond bounds [0 .. 39]

*** -[__NSArrayM objectAtIndex:]: index 60 beyond bounds [0 .. 59]

*** -[__NSArrayM objectAtIndex:]: index 80 beyond bounds [0 .. 79]

复现过程:

1.根据ama上的log记录用户行为进行多次复现操作时,没能复现出此问题。

2.后来开发说可能是列表的问题,当时改过老功能代码,然后我就从列表找起,最后复现出此crash。

操作步骤:

1.新房--地图找房--点击小区标点(超过20套);

2.小区房源列表,加载出数据后,把网络切为无效网络;

3.再滑动列表加载更多,弹出加载失败提示框,点击取消,再进行滑动列表;

结果:

再进行滑动列表时发生crash。

根本原因:

请求参数city id、page、pagesize,列表里有个逻辑是总数>page x pagesize显示出加载更多,总数<=page x pagesize不显示加载更多。举例:总数=25,第一页显示1x20=20个,此时切换成无效网络,请求第二页时,page自动+1,page x pagesize=2x20=40,实际上加载失败了还是20个,此时“加载更多”需要显示在41行,但是只有21行,所以发生crash。

解决方法:

修改为总数与缓存进行比对,比如总数=25,第一页显示1x20=20个,此时切换成无效网络,请求第二页时,总数与缓存的20个进行比对,就不会出现此crash。

总结

1.在RC阶段修改一个bug,动了底层代码导致,测试不知情。(bug一定要搞清楚产生的原因和如何修复)

2.作为QA这个bug当时验证的时候应该在多检查一下相关的功能,毕竟是改的老功能的地方不排除有带出新bug的可能,虽然不一定就能发现那个问题,但是这个习惯还是要养成。

3.另外开发过程中这种对新列表和单页的网络情况都要做判断包括两种网络(无网络和无效网络) 。

二、

量大crash日志:

*** -[NSPlaceholderString initWithString:]: nil argument

复现过程:

1.线上发现该问题

2.开发通过log定位到问题的方法和原因:  使用到了initWithString方法,当cityid取到的城市name为空值时,传入到该方法中应用crash

3.未想到在何种步骤下cityid会拿到空的name名称,先在模拟器上模拟城市name为空值传入的情况,确认该情况报的crash确实和线上一致

4.追究真机上重现步骤,开发给出各种设想(城市名称表坏了、用户越狱了、定位到的城市为未开通城市从安居客拿到cityid但新房没开通…),逻辑上均说不通

5.根据开发的设想和bu*生的原因,我们最终在真机上找到重现步骤(开始以为跟定位有关系,最终逐个排除step,确定下key step)

操作步骤:

1.全新启动app,进入首页;

2.假如首页显示的当前城市是“北京”,此时,不要做任何操作,直接再切换一次城市“北京”;

3.再进行切换新房tab;

结果:

点击新房tab时发生crash;

根本原因:

1.代码中有一个逻辑cityid等其他一些筛选条件,再切换城市时,会被清掉,另外外面还有一套逻辑是:当切换的城市与当前城市相同时,缓存数据(cityid,page等)被清掉了,但是没有重新赋cityid,导致cityid为空。

2.使用了initWithString方法,当cityid取到的城市为空值时,传入到该方法中应用crash(方法使用问题,此方法本身缺陷)。

解决方法:

1.当切换的城市与当前的城市相同时,不清除缓存数据。

2.不使用initWithString方法,改成苹果系统中的方法lblCityName.text方法,如

if (self.filter.cityID) {

if ([[RTCityManager sharedInstance] cityNameForCityID:self.filter.cityID] == nil) {

//            [[RTCityManager sharedInstance] setSelectedCityID:@"11"];

lblCityName.text = @"城市未开通";

}

else

lblCityName.text = [[RTCityManager sharedInstance] cityNameForCityID:self.filter.cityID];

}

另外当cityid真的为空时,又打了一个补丁,城市显示为“未开通”

总结:

1.此问题之前一直隐藏的问题,当时的表现是按照上面操作,提示加载失败,当时以为是网络问题,而很容易被忽略掉。

2.如果不能复现出此问题,先根据初步判断进行在模拟器上模拟一些情况进行是否与线上crash报的错误一致,从而再进一步进行问题的定位。

3.之前在户型选择的时候曾出现过类似问题,再有选择项时,一定要对重复选择项多做测试。

4.在使用initWithString等方法的时候一定要考虑一些边界情况,对一些空的情况做下处理。

5.之前4.3版本上存在过渠道包打错渠道包的问题,在打渠道包时,一定要注意是QA最后测试的版本。这个以后也要引起注意。

6.在RC阶段,如果没有大的问题一定不要轻易的动底层代码,如果问题严重一定要动底层代码的话QA一定要了解清楚可能影响的模块,进行评估风险。

三、

bug描述:iOS新房4.5:连续18次进入新房地图找房时,发生crash。

复现过程:

1.daily build的最后两天发现的此问题,然后就提了一个偶发bug:新盘首页锁屏放置了大概10分钟左右,解锁后进入地图找房,地图无法显示;

2.两天内出现了3-4次,应该会有必现的规律,找开发确认此问题,当时的猜测是(进入地图找房请求数据的时候卡住了,api的问题等等);

3.接下来从地图入手,新盘地图找房和新房地图找房来回切换,让开发连接真机调试的时候发现问题所在

操作步骤

新房tab--地图找房--返回(连续操作18次--iphone5)

根本原因:

在新房地图找房返回时,没有内存没有及时回收。

总结:

今后在测试中对于一些新加的功能模块,或改动较大的模块,适当的进行一些类似压力的测试(观察内存和cpu的使用情况)。

当时的一点思考总结:

1.当你在和开发人员确认问题的时候,一定要搞清楚原因,特别是bug如何产生和如何修复的。

2.项目合作时,要更加的主动(比如在发包的时候,可能邮件描述的不清楚,要主动去确认,修改了那些东西?底层的东西有没有动,如果动了可能那些模块会受到影响等等),多沟通多确认。

3.花一点时间去挑战偶发的crash等奇怪现象,其实bug正常来看的话都有必现的步骤。

4.多看代码(在空闲的时候多去看看代码,了解了解具体的逻辑是怎么样的)

以上内容不敢说对所有的人都有所用,但是应该能对部分人有所帮助和启发。

对于测试人员来说一定要注意:

1.当我们去做某一个项目时,一定要搞清楚架构、功能等是如何实现的,系统之间是如何交互的,使用到哪些技术,等等(不懂多问、多查资料,多思考,多总结);

2.测试前准备:数据准备、流程图、接口、数据库、兼容性等都梳理清楚,搞明白透彻,测试前分析到位;

3.用例设计:按照步骤2的分析进行用例的编写,除了正常的流程外,多考虑其中的异常场景。说到这里,可能会有朋友说,小需求我哪里有时间写测试用例,时间那么紧急。用例一定要写,小需求也要把测试点写出来,如果没有测试点,怎么去测?如何能更好的保证质量?

4.用例评审:保证三方(产品、研发、测试)需求的统一性,另外,尽可能的达到用例的全面性,对遗漏的用例做补充。

要做到:不懂多问、多沟通、多查资料、多思考、多总结。


了解更多请关注微信公众号:测试架构师

                                                                           BUG,带给我的思考


BUG,带给我的思考的更多相关文章

  1. android一个下拉放大库bug的解决过程及思考

    android一个下拉放大库bug的解决过程及思考 起因 项目中要做一个下拉缩放图片的效果,搜索了下github上面,找到了两个方案. https://github.com/Frank-Zhu/Pul ...

  2. 关于线上的bug什么时候修复的思考

    这里系统专门指的是那种用户量大的系统,比如有几百万或者上千万的注册会员.因为小系统因为用户量少,不存在这种思考,考虑有时候是多余的.另外还有内部系统,给自己公司内部人员使用的,即便是出现了问题,也不会 ...

  3. 一个毕生难忘的BUG

    记得以前接手过一个Java项目,服务器程序,直接让Jar在linux上跑的那种, 这个项目由两个web服务组成,也就是两条Java进程,主进程 xxx.jar,辅助进程 xxx_helper.jar. ...

  4. 带着问题写React Native原生控件--Android视频直播控件

    最近在做的采用React Native项目有一个需求,视频直播与直播流播放同一个布局中,带着问题去思考如何实现,能更容易找到问题关键点,下面分析这个控件解决方法: 现在条件:视频播放控件(开源的ijk ...

  5. 巧用浏览器F12调试器定位系统前后端bug

    做测试的小伙伴可能用过httpwatch,firebug,fiddler,charles等抓包(数据包)工具,但实际上除了这些还有一个简单实用并的抓包工具,那就是浏览器的F12调试器. httpwat ...

  6. 怎样跟程序猿谈一场没有Bug的恋爱

    <iframe width="580" height="90" align="center,center" id="cpro ...

  7. Git速成学习第六课:Bug分支

    Git速成学习笔记整理于廖雪峰老师的官网网站:https://www.liaoxuefeng.com/ 当你接到一个修复代码为101的任务的时候,很自然的你想创建一个分支issue-101来修复它,但 ...

  8. 一个历时五天的 Bug

    一个程序员在没有成长成为架构师之前,几乎都要跟 Bug为伴,程序员有很多时间都是花在了查找各种 Bug上. 我印象深刻的一个Bug, 是一个服务器网络框架无锁队列的 Bug .那个 Bug 连续查找了 ...

  9. 【Not BUG】微软Winform窗体中设计上的Bug,会导致程序编译失败?不,这不是BUG!

    这不是BUG!!! 原文地址: https://www.cnblogs.com/thanks/p/14302011.html 现在让我们回忆一下原文 原文的操作步骤: 1. 新建一个Window Fo ...

随机推荐

  1. monkeyrunner脚本录制

    1.在窗口输入 monkeyrunner monkey_recorder.py  调用录制脚本工具 2.在窗口输入 monkeyrunner monkey_playback.py  d:\game   ...

  2. asp&period;net项目中通过Web&period;config配置文件及文件夹的访问权限!

    描述:在开发中我们通常会碰到这样的问题,例如:在项目的根目录下面有一个文件或者文件夹需要用户登陆后才能访问.如果用户在没有登录的情况下访问该文件或者该文件夹下面的文件时,直接拦截重定向到对应的登陆页面 ...

  3. spring:bean的定义

    一个完整的Bean的配置文件: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE beans ...

  4. OkHttpUtils

    对okhttp的封装类,okhttp见:https://github.com/square/okhttp.目前对应okhttp版本3.3.1. 用法: Android Studio compile ' ...

  5. 【PHPsocket编程专题&lpar;实战篇③&rpar;】构建基于socket的HTTP请求类

    该代码是两年前写的,现在看起来有点渣了,仅仅是提供一个思路,现在做一些Api开发的时候官方会有一些SDK,这些SDK其实原理都是通过socket来通讯的,其实我个人主张用curl更方便,当然前提是你的 ...

  6. 怎么关闭InstantRun

     Settings → Build, Execution, Deployment → Instant Run and uncheck Enable Instant Run. 

  7. jQuery如何创建元素

    1.$("<ul>").attr("id","taglist").appendTo("#tagCloud") ...

  8. perl 读取Excel写入txt 乱码

    用perl读出excel的内容(中文),然后输出在txt中乱码,但是打印在控制台正常. 解决办法: use Encode qw/from_to/; from_to($value, 'gb2312', ...

  9. intelij idea设置和使用git

    一.通过git从远程拉取代码到idea本地 1.git配置 2.通过git拉取远程仓库代码 图一: 图二: 3.下一步下一步即可 二.share本地仓库代码到git上 注意: 通过share会变成一个 ...

  10. KnockoutJs学习笔记(八)

    with binding用于创建一个新的绑定环境(binding context),包含with binding的元素的所有子元素都将处于指定的object的环境限定内. 下面是一个简单的使用with ...