前言:

  这篇文章是基于Android系统定制和维护而写的,所以里面的内容与Android相关也是说系统是Android,语言是Java,特点是没有明确的需求行为规格定义,只有代码,很多行为也比较诡异,代码架构不是很完美,崩溃,异常比较常见(RuntimeExceptions)。虽然是基于Android的,但是方法是通用的。

  什么是Bug

  首先要明白什么是Bug,这点可能不同的人(测试和开发)有不同的理解,不同的公司也会有不同的标准。但是通俗的来讲,Bug是指未预期的行为(unexpected behaviors),比如系统崩溃(Crashes),发生异常(Exceptions),或功能失常(Malfunctions),比如说点击了保存,但实际上没有保存,点击了发送却没有发送成功。

  那什么又是预期行为(Expected behaviors)呢?预期行为通常是指需求说明书中规定的行为,但是很多系统(比如Android)完全没有需求或规格说明书,所以更多的时候判断的标准是常识和经验,或与其他软件系统进行对比。比如说虽然没有需求规格书,但是通常意义上保存应该能把文件或用户所编辑的内容写进磁盘文件,如果没有成功,那行可以认定为Bug。所以说Bug也是受主观因素影响的。

  与Bug打交道的人

  软件的理想情况是程序员所写的程序(算法)都是正常的,但是有理论证明这是不可能的,没有任何一个算法是完全正确的,另外只要是人是犯错误。所以现代大多数的软件都这样来保证它的正确性,开发人员交给测试人员软件,测试人员来保证它的质量,通过测试Bug,当软件的Bug在一定的允许的范围内(小于10个)可以认定软件已达到预期了,能正常工作并且可以发布。

  在这一过程中涉及三组人:一个是开发人员,一个是测试人员,另外是管理层。很多大公司的开发人员与测试人员都分属不同的部门。开发人员负责开发出可测试的软件版本,测试人员对软件进行测试,测试出Bug后提交给开发人员,开发人员再解决Bug。通常他们都有来自管理层的压力和绩效考核的压力,也是说管理层对测试人员说:你要尽可能多的提交Bug,无论用什么方法,或者你每天必须提交3个Bug;另外测试人员的绩效也与其所提交的Bug数量直接相关。管理层也会对开发人员说:你要在Milestone前把所有的Bug都解掉,上个星期的Bug怎么还没解掉,你想不想干了?另外开发人员的绩效也会与Bug数量有关,如果有Open的Bug会扣新水或奖金等。

  这样一来,原本比较简单清纯的关系变的有些复杂了,无论是测试人员还是开发人员会把人的本性加进来,把政治和功利也带了进来,像测试提交了不是Bug的Bug,或是开发人员强行关闭Bug都是常有的事儿。因此,测试与开发人员便有些战争:

  开发:你这不是Bug,这个行为是这样设计的?

  测试:但是这样设计很不合理!

  开发:那这个要去找UX设计的人?对于行为的修改我们不能做主

  测试:我不管那么多,我只管测试

  开发:#%^@&$...

  ....

  测试:你为会么关我的Bug

  开发:因为它无法复现

  测试:但当时我的确是遇到了

  开发:那你再复现出来吧

  测试:@#$%^...

  Bug的常见分类

  如前所说Bug是未预期的行为。所以Bug常见的类型有:崩溃(Crashes),异常(Exceptions),功能失常(Malfunctions),差劲的用户体验(Bad user experiences),未实现的行为和功能。

  Bug的复现机率

  这个是特别是值得注意的,首先Bug描述上面写的复现机率只是测试人员在当时的现场Bug出现的机率,另外这个也是比较主观的,比如试了三次出一次,有的人认为是必现的,也有的人认为是有一半机率(Above 50%)。

  但是经过这几年解Bug总结的经验发现,真正的随机出现的Bug只有与线程时序有关的逻辑才会有。其他的随机Bug并不是随机,只可能是测试不太清楚操作步骤和所有的数据或当时的环境现场。

  如何解决Bug

  1、弄清楚Bug究竟是什么样的问题

  拿到Bug后,不要着急去复现,首先要弄明白Bug究竟涉及到哪些行为,哪些操作,当时的现场和环境是什么样的,用了什么样的数据,操作到哪一步出现了问题等等。因为测试人员对Bug的描述是很主观的,可能不太清楚,所以要与测试人员进行沟通,弄明白这些问题:

  当时的配置,环境,现场是什么样子的?

  涉及到哪些行为?

  进行了什么样的操作?

  操作到哪一步出现了问题?

  出现了什么问题?

  如果说是功能失常,或差劲的用户体验或未实现的行为,那么测试所期待的行为又是什么样子的?

  测试人员有没有附上日志,截屏或其他调试信息。

  2、如果Bug是崩溃或异常

  先不要忙着去复现,因为对于崩溃和异常,日志当中肯定会有崩溃和异常的直接相关信息,通常这能定位出问题,比如对于Java语言来说如果出现未Handle的异常,那么日志中肯定会有异常相关的信息调用栈等。所以通过日志文件可以定位出问题出现的源代码。这样多了一个线索,因为你可以通过源代码来推测是什么导致了这个异常,可能做了什么操作,环境现场发生了什么变化等,通常来讲这比测试人员提供的信息更有参考性。