jjzjj

软件测试遇到bug怎么分析,看看字节5年老司机是怎么秀操作的...

白码会说 2023-10-08 原文

为什么定位问题如此重要?

可以明确一个问题是不是真的“bug”

很多时候,我们找到了问题的原因,结果发现这根本不是bug。原因明确,误报就会降低

多个系统交互,可以明确指出是哪个系统的缺陷,防止“踢皮球”,提高问题解决的效率

增强开发对测试的信任度,沟通更有效,配合的更好,开发修改bug时效增强

更有效的了解系统的内部逻辑、数据流处理流程,更能提高测试人员的水平,缺陷修复后,影响的测试范围评估更精准,复测更准确

可以降低缺陷率

这个可以说是最重要的。在bug系统中,会要求开发人员记录bug产生的原因。只有我们自己对bug有一个较全面的认识,才会判别出开发写的是不是真正的原因,也才能有助于我们后续对bug进行分析归类,根据bug分析,有针对性地未雨绸缪,进而提升产品质量,降低缺陷

01、定位原因之前

遇到问题时,先别急着去定位原因。

1、保存bug产生的记录:

首要做的是保存bug产生的记录,保证可以复现。

为什么要保存记录?因为如果以后不能复现,那就不能证明bug的存在。

2、排除低级问题:

然后是排除QA的低级问题,常见的低级问题:

【hosts不对】

hosts文件主要是加快某个域名或者网站的解析速度,从而达到快速访问的作用,也可以屏蔽网站。

hosts异常可能会导致部分网页无法访问,能够加载,但是网页无法正常显示。

【网络不通】:抓包、ping

工具的影响导致的,例如fiddler

以及操作姿势不正确等。

3、排除数据问题(脏数据):

有时候会遇到服务端报500错误,查看日志后,报空指针,那么很有可能就是数据库中关联表的数据被人为删掉导致的。

脏数据:从目标中取出的数据已经过期、错误或者没有意义,这种数据就叫做脏数据

脏读:读取出来脏数据就叫脏读

02、定位问题的思路

排查顺序:

用户环境层面 -> 展示层面 -> 逻辑控制层面 -> 服务层面 -> 数据库层面

1、用户环境层面

主要是指基础环境是否可以使用。比如:

网络是否ping通

ip和端口配置是否正确

jdk版本是否符合标准

有可能是由于jdk版本不兼容导致系统运行异常,这种问题根据实际情况来决定要不要兼容。

网络设了代理

弱网(如js/css未加载完全、请求超时)

浏览器不支持

系统版本不支持

数据库被删除

测试环境脏数据

项目配置开关

测试环境切了分支等

检查完成后,可以转到第二步

2、用户展示层

用户在使用过程中,通过查看等操作发现的一些问题:

页面样式(css样式问题)

交互过程中js的提示(js交互问题)

终端控制的提示信息

文本的展示(html文本问题)

3、逻辑控制层

用户操作过程中,业务的处理逻辑有没有按照前期的设计实施。或者中间环节出现异常,比如缓存服务器(如redis)、消息中间件(如rabbitMQ)、数据存取中间件等。

4、服务层

服务层往往检查服务器的配置,如可能是tomcat配置、nginx配置、jdbc配置等的问题。测试人员最好能够了解下它们的各项配置。

5、数据库层

可能出现测试环境和正式环境数据库版本不同,前后端数据格式、长度限制不同。用户操作完成后,交易流程非常顺畅,这样也不代表整个交易没有问题,还需要测试人员检查数据库登记的表和字段是否正确

如果发现登记的字段与预期的结果不一致,则可以查看日志,检查请求报文送的字段是否正确,是否与前台填写的一致

有的一个操作会登记多张表,所以要检查多张表登记或者更新的是否正确,测试人员也需要对被测系统的数据表结构熟悉

6、经验法则

有经验的测试人员对于有部分bug已经见过多次,能够很快找到根源,直奔主题,迅速报告或者解决bug

7、其他

常见的bug可能还有构建方面的原因

比如代码本身没错,但是合并代码到主干后出现了问题

比如代码存在冲突时手动解决的情况

03、定位问题的方法

1、常用的定位策略:

常用的定位策略分为三类:原始类(brute force)、回溯类(backtracking)、排除类(causeeliminations)

原始类定位方法

原始类定位方法是最常用也是最低效的方法,只有在万般无奈的情况下才使用它,主要思想是“通过计算机找错”。

回溯法

回溯法能成功地用于程序的排错

方法是从出现bug征兆处开始,人工地沿控制流程往回追踪,直至发现出错的根源,不幸的是程序变大后,可能的回溯路线显著增加,以致人工进行完全回溯到望而不可及。

排除法

基于归纳和演绎原理,采用“分治”的概念。

首先确定所有与bug出现有关的所有数据,设想一个导致bug的原因,用这些数据证明或反驳它。或者一次列出所有可能的原因,通过测试一一排除。只要某次测试结果说明某种假设已呈现倪端,则立即精化数据,乘胜追击

2、查看状态码

4xx状态码:一般表示是客户端问题(当然也有可能是服务器端配置问题),比如:

发生了401,那么要看下是否带了正确的身份验证信息

发生了403则要看下是否有权限访问

404则要看下对应的URL是否真实存在

5xx状态码:一般表示服务端出现问题。比如:

发生了500错误,则表明是服务器内部错误,这个时候要配合服务器log进行定位

发生了502错误则可能是服务器挂了导致的问题

发生503错误可能是由于网络过载导致的问题

发生504错误则可能是程序执行时间过长导致超时

3、查看服务器日志

如果发生5xx问题,或者需要检查后端接口执行的sql是否正确,我们最常见的排查方法就是去看服务器日志,比如tomcat日志。开发人员一般会打出关键信息和报错信息,从而找到问题所在,所以,测试人员也要养成看日志的习惯。

4、检查配置

很多时候,bug不是代码的问题,而是tomcat配置、nginx配置、jdbc配置等的问题。在这个层面上,测试人员最好能够了解下它们的各项配置,在发现问题后可能就会想到这方面的问题。

5、查看需求文档

有时候,前端和服务端的交互都正确,但是从测试的角度看不合理。这个时候,我们应该翻翻需求文档。如果和需求文档不符,那么就要看下改什么比较合理,是改前端,还是改服务端,或者两者都要改。

这里有一个原则,就是前端尽可能少地去承担逻辑,只负责渲染展现。当然,不要以为需求文档就全部正确,它也可能会有错误,我们也应该去发现需求文档的bug,然后再去协调PM,敦促FE或者RD进行修改。

6、向开发寻求可测性支持

有时候,涉及到开发过程的一些测试,也需要开发提供可测性支持。

比如,要查看接口给另一个接口发的请求是否正确,可以让开发打印出完整的请求log,还有一些逻辑开关、修改页面数据条数等,都属于可测性支持的范畴。

04、bug定位常用工具

Firefox——firebug、web developer、live http - headers、http fox

IE插件——httpwatch

第三方工具——fiddler

慢速网模拟工具——firefox throttle

05、如何区分前端/后端bug

为什么要区分前端/后端BUG?

如果是一个多人开发的系统,不能明确定位到这个bug是谁造成的,容易提交给错误的开发人员。

同时提交给前后端开发人员,每个人都会有依赖心理,bug会像皮球一样被开发踢来踢去,耽误开发解决bug的时间。

另外,如果团队规模较大,或者由各地的项目组拼凑而成,势必会增加沟通成本,这更需要我们在类似禅道或者Jira等项目管理软件中提交bug时,先指明是谁的bug,避免互相踢皮球的现象。

所以测试必须要自己学会区分出是前端还是后端bug,经过bug分类处理,整个团队的效率都会有所提高。

前后端BUG各有什么样的特点?

1、利用抓包工具来进行分析

一般有httpwatch,firebug,fiddler,charles等抓包(数据包)工具。

httpwatch,firebug都是浏览器的插件,需要额外下载

fiddler,charles也需要额外下载安装包另行安装

还有一个简单实用的抓包工具,那就是浏览器的F12调试器

2、定位前端的bug

前端的bug通常是功能、界面和兼容性等有关,涉及到jstl,jsp,js,css,html方面比较多。bug主要有两块:

JS相关

页面

3、定位后端的bug

后台涉及到servlet,jms,ejb,还有很多框架struts,hibernate,spring,ibatis等

bug 比较难改,但是好找,主要就是看控制台报错,然后定位错误行号。如果配置文件没有问题,那么一般的报错就是空指针,或者是数组下标越界。看附近变量,看方法的参数基本上都可以定位错误。

06、定位完问题后

在发现问题或者定位到问题原因后,一定要进行一步,就是再次确认问题。所谓确认问题,就是弄清楚问题是否每次都发生,还是概率事件,或者是工具相关的问题:

比如换个浏览器是否依然出现?如果换个浏览器不出现的话,很可能就是前端的兼容性问题。

比如翻页控件,待测的系统有很多页面都有翻页控件,那么就要看下是否每个页面都会出现这个问题,进而报bug时进行统一说明,也更加方便开发人员批量处理,防止漏改。

技能提升

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走

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

关注我的微信公众号:【程序员小濠】即可获取这份资料了!

如果你不想再体验一次自学时找不到资料,没人解答问题,坚持几天便放弃的感受的话,可以加入我们的群:779450660 大家一起讨论交流,里面也有各种软件测试资料和技术交流。

如果对你有帮助的话,点个赞收个藏,给作者一个鼓励。也方便你下次能够快速查找。

有关软件测试遇到bug怎么分析,看看字节5年老司机是怎么秀操作的...的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  3. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  4. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  5. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  6. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  7. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  8. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

  9. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

  10. ruby - 怎么来的(a_method || :other) returns :other only when assigning to a var called a_method? - 2

    给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R

随机推荐