BUG,带给我的思考
今天打开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.根据开发的设想和bug产生的原因,我们最终在真机上找到重现步骤(开始以为跟定位有关系,最终逐个排除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,带给我的思考的更多相关文章
- android一个下拉放大库bug的解决过程及思考
android一个下拉放大库bug的解决过程及思考 起因 项目中要做一个下拉缩放图片的效果,搜索了下github上面,找到了两个方案. https://github.com/Frank-Zhu/Pul ...
- 关于线上的bug什么时候修复的思考
这里系统专门指的是那种用户量大的系统,比如有几百万或者上千万的注册会员.因为小系统因为用户量少,不存在这种思考,考虑有时候是多余的.另外还有内部系统,给自己公司内部人员使用的,即便是出现了问题,也不会 ...
- 一个毕生难忘的BUG
记得以前接手过一个Java项目,服务器程序,直接让Jar在linux上跑的那种, 这个项目由两个web服务组成,也就是两条Java进程,主进程 xxx.jar,辅助进程 xxx_helper.jar. ...
- 带着问题写React Native原生控件--Android视频直播控件
最近在做的采用React Native项目有一个需求,视频直播与直播流播放同一个布局中,带着问题去思考如何实现,能更容易找到问题关键点,下面分析这个控件解决方法: 现在条件:视频播放控件(开源的ijk ...
- 巧用浏览器F12调试器定位系统前后端bug
做测试的小伙伴可能用过httpwatch,firebug,fiddler,charles等抓包(数据包)工具,但实际上除了这些还有一个简单实用并的抓包工具,那就是浏览器的F12调试器. httpwat ...
- 怎样跟程序猿谈一场没有Bug的恋爱
<iframe width="580" height="90" align="center,center" id="cpro ...
- Git速成学习第六课:Bug分支
Git速成学习笔记整理于廖雪峰老师的官网网站:https://www.liaoxuefeng.com/ 当你接到一个修复代码为101的任务的时候,很自然的你想创建一个分支issue-101来修复它,但 ...
- 一个历时五天的 Bug
一个程序员在没有成长成为架构师之前,几乎都要跟 Bug为伴,程序员有很多时间都是花在了查找各种 Bug上. 我印象深刻的一个Bug, 是一个服务器网络框架无锁队列的 Bug .那个 Bug 连续查找了 ...
- 【Not BUG】微软Winform窗体中设计上的Bug,会导致程序编译失败?不,这不是BUG!
这不是BUG!!! 原文地址: https://www.cnblogs.com/thanks/p/14302011.html 现在让我们回忆一下原文 原文的操作步骤: 1. 新建一个Window Fo ...
随机推荐
- 日历视图(CalendarView)组件的功能和用法
日历视图(CalendarView)可用于显示和选择日期,用户既可选择一个日期,也可通过触摸来滚动日历.如果希望监控该组件的日历改变,可调用CalendarView的setOnDateChangeLi ...
- Java学习之旅基础知识篇:数组及引用类型内存分配
在上一篇中,我们已经了解了数组,它是一种引用类型,本篇将详细介绍数组的内存分配等知识点.数组用来存储同一种数据类型的数据,一旦初始化完成,即所占的空间就已固定下来,即使某个元素被清空,但其所在空间仍然 ...
- 采用FirePHP调试PHP程序
采用FirePHP调试PHP程序 FirePHP是什么? FirePHP是一个利用Firebug console栏输出调试信息方便程序调试.这一切只需要调用几个简单的函数. 他看起来是怎么个样子? 1 ...
- HttpServletRequest和ServletRequest的区别
servlet理论上可以处理多种形式的请求响应形式,http只是其中之一所以HttpServletRequest HttpServletResponse分别是ServletRequest和Servle ...
- 关于Task的一点思考和建议
前言 本打算继续写SQL Server系列,接下来应该是死锁了,但是在.NET Core项目中到处都是异步,最近在写一个爬虫用到异步,之前不是很频繁用到异步,当用到时就有点缩手缩尾,怕留下坑,还是小心 ...
- 语句 if else
语句 语句是指程序命令,都是按照顺序执行的.语句在程序中的执行顺序称为“控制流”或“执行流”. 根据程序对运行时所收到的输入的响应,在程序每次运行时控制流可能有所不同. 语句间的标点符号必须是英文标点 ...
- php面向对象(OOP)---- 验证码类
PHP常用自封装类--验证码类 验证码是众多网站登陆.注册等相关功能不可以或缺的功能,实现展示验证码的方式有很多,这篇文章作者以工作中比较常用的方法进行了封装. 逻辑准备 要实现一个完整的验证码,需要 ...
- Myeclipese改变背景色
https://www.baidu.com/s?wd=Myeclipese%E6%94%B9%E5%8F%98%E8%83%8C%E6%99%AF%E8%89%B2&ie=utf-8& ...
- swift 运算符快速学习(建议懂OC或者C语言的伙伴学习参考)
昨晚看了swift 的运算符的知识点,先大概说一下,这个点和 c 或者oc 的算运符知识点一样,都是最基础最基础的.其他的最基本的加减乘除就不多说了.注意的有几点点..先说求余数运算: 一 :求余数运 ...
- block循环饮用解决
在block中使用self会引起循环引用导致无法释放. 解决: __weak typeof(self) weakSelf = self; 例如: NSLog(@"init--> val ...