白盒测试 IDEA 远程调试 Java 代码实践及心得分享

Tester_Ella · 发布于 2017年07月11日 · 最后由 haifushi 回复于 2017年07月14日 · 最后更新自管理员 seveniruby · 1131 次阅读
本帖已被设为精华帖!

刚工作那会,每听人讲起通过远程调试代码来定位bug都觉得很高端,后来在工作中不断尝试,到现在远程调试代码已成为自己的一种常用辅助测试手段,不仅减少与开发的沟通成本,在提升测试效率的同时,也增加了对代码的理解程度,提升了测试的深度,不可不说优点多多。

下面简单介绍下使用Intellij IDEA进行远程调试需要进行的配置及服务端的相关配置,并用一个实例简单介绍下远程调试的一般过程,最后分析下我认为的QA进行远程代码调试的一些优缺点。

一、本机Intellij IDEA远程调试配置

1、打开Inteliij IDEA,顶部菜单栏选择Run-> Edit Configurations,进入下图的Run/Debug Configurations界面。
2、点击左上角'+'号,选择Remote。(注意不是tomcat server->remote,之前在某篇教程上看到是这个,怎么弄都不对。)
分别填写右侧三个红框中的参数:Name,Host(运行代码的服务端ip),Port(想要指定的远程调试端口)。
3、点击界面右下角Apply按钮即可。
avatar

二、服务端增加指定JVM启动参数,以支持远程调试

在Tomcat启动脚本TOMCAT_HOME/bin/catalina.sh的首行或CATALINA_OPTS字段说明行后添加CATALINA_OPTS参数配置,参数值复制上图中间红框中的内容即可:

CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=28000"

配置添加之后,重启tomcat即可生效。

三、使用远程调试定位代码问题实例

完成一二两步就可以开始远程调试了,下面以一个实例,来说明一下远程调试的一般过程。

1、发现问题

之前一次新功能测试中,需求是在续费的第二个页面增加一条显示信息,在续费的第一个页面填写相关信息点击下一步按钮时,本应该直接进入下一页,但实际跳转到ERROR页,查看url发现相关接口返回了自定义返回码500,提示服务器错误。

2、查看日志,定位问题代码位置

通过查看业务日志,发现是在PaymentRestServiceImpl.java中的448行的availableRenewMonths方法中抛了NPE(java.lang.NullPointerException)。
avatar

3、查看问题代码前后的业务逻辑

通过代码走读可以看出,这个方法用于获取可选的续费时间段,对systemSettingService.defaultRenewDurations()进行遍历时抛了NPE。
avatar

4、打断点,进行远程调试

在PaymentRestServiceImpl.java的448行打上断点(断点位置可视具体情况而定)。
在Intellij IDEA顶部菜单栏选择Run-> Debug 'Remote界面中指定的Name';或者在下图中间红框中选择对应Name后点击右侧的绿色图标,在下方的Console区出现如下提示语则表示已成功连上远程服务器。
注意:本地代码分支及版本号要与远程服务端的代码一致。
avatar
重新在续费页面输入信息点击下一步按钮时,调试程序会停留在断点处,即为下图左侧的勾号所在位置。IDEA界面下方会出现Debug视图,左下角Frames区是方法调用堆栈区,第一行显示当前程序停留的代码行,中间Variables区显示变量信息,右下角Watches区可添加观测变量。
中间红框中为5个常用的调试按钮,从左到右分别为:
1、step over:执行下一行,有方法调用则执行后返回,到下一行
2、step into:执行下一行,有自定义方法则进入其中(不会进入官方类库的方法)
3、force step into:执行下一行,任何方法都能进入
4、step out:跳出当前方法返回被调用处的下一行
5、drop frame:返回当前方法的调用处,即Frames区的下一行显示的代码处
avatar
在右下角Watches中添加观测变量systemSettingService.defaultRenewDurations(),值为NPE。点击step into按钮进入该方法中,可以看出,该方法要返回续费时的可选时间段getRenewDurations,但代码逻辑却以购买的可选时间段getPurchaseDurations非空作为判断条件,但为什么抛NPE呢?查询redis中对应的配置项信息,发现配置项中只有购买的可选时间段,没有续费的可选时间段,所以正好符合代码中的非空判断,所以返回了NPE。到这里就可以确定问题代码的根源了。
avatar

5、问题刨根问底及后续改进

作为一名负责任的QA,到这里问题还没结束,还需要对问题进行进一步的分析。
续费功能之前一直在用,为啥突然出问题呢?想起之前产品提需求,要修改购买时的可选时间段,应该是跟这个有关系。然后在jira上提bug给开发修复,描述下现象,再贴上如上截图,问题就一目了然了。然后询问下开发,导致问题的根本原因,是因为之前续费和购买获取可选时间段的方法是公用的,后来购买逻辑变更,续费重写方法,但复用之前代码时getPurchaseDurations方法没有全改掉,导致前后逻辑不一样。

但我在git上查看提交购买可选时间段功能的代码版本,并没有看到上述问题代码的修改。初步猜测可能是开发没有按照规范提交代码,一个功能点分多个版本来提交了。然后跟开发确认了一下这个猜想,发现确实是把问题代码的修改提交在另一个功能点的代码版本中了。针对这个问题跟开发商量了一下,以后一个功能点的修改在git上只提交一次,这样方便查看代码变更。

业务逻辑的变更,特别是代码重构时,往往会出现类似上面的修改功能A导致功能B异常的一些问题。这种情况比较好的测试方法是进行变更代码走读,然后设计与代码变更相关的回归用例,保证测试用例的有效性。

上面讲的例子比较简单,但也比较典型。在业务很复杂时,问题定位时可能需要开发的一些帮助。若对代码很不熟或业务逻辑实在太复杂时,考虑时间成本,可以直接让开发进行远程调试,自己搬个凳子坐旁边看他如何操作,遇到不懂的地方就要借机多问一些问题,能学一点是一点,看几次慢慢就会上手了。

四、QA进行远程代码调试的一些优缺点

以上文例子来说,若QA同学不进行远程调试,而是直接反馈开发,续费的时候接口返回500,一般会发生如下几个来回的交流:
1、开发根据QA描述的现象,自己在页面操作以重现问题
2、看日志,并通过远程调试进行问题定位,然后反馈QA问题所在
3、QA针对开发的描述理解问题所在,并设计回归用例(对代码不熟的话的时候听开发的问题描述常常是模棱两可)
4、开发代码修复并重新部署后,QA进行回归测试
若QA同学自己能进行代码远程调试来定位问题,步骤1可省略,步骤3前半部可省略,且设计回归用例更具有针对性,步骤2的执行者从开发变成QA。

下面罗列下个人理解的QA进行代码远程调试的优缺点:
缺点:
1、测试时间开销长,在测试任务很紧时不适用
2、有一定门槛,需要QA对代码有一定的理解
优点:
1、节省双方的沟通成本
2、锻炼QA同学独立排查问题的能力
3、增加对代码的理解程度,提升测试的深度
4、增加开发对QA同学的认可度,以后沟通合作起来更方面
5、提升QA自身的成就感

关于缺点1,我认为要做一个有追求的QA,进行基本的代码走读和分析能力是必备的技能之一。只满足于表面的功能测试不利于以后的发展。

关于优点4,想特别说明一下。我记得每每反馈开发代码哪行哪行写错了,应该如何改,特别是在发现一些复杂业务逻辑的问题时,开发同学都会赞叹QA同学很厉害。开发对QA同学的工作会越来越认可,在写代码时也会更谨慎一些,毕竟对开发来说,被QA指出哪里哪里写错了肯定多少会有些尴尬的。但是在跟开发沟通的时候要注意使用比较友好的口气,千万别用指责的口气,这样肯定会恶化双方的关系,不利于后续的合作。在测试过程中肯定会有需要开发配合的地方,跟开发保持良好的关系,开发也会乐意帮忙。

综合来讲,在测试时间不是很紧时,遇到问题时QA直接进行远程调试去排查问题还是很适用的。而且随着对项目代码的理解程度的加深,定位问题的速度会越来越快。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 7 条回复
3341

请问下什么场景需要远程调试,本地直接拉取对应分支代码直接调试不是也可以么?

13997
3341jaychang1989 回复

如果出现的问题只在特定环境出现时必须用远程调试(如某问题在测试环境必现,但在开发环境ok),一般情况下在本地直接调试也是可以的,但还需要本地起tomcat服务,相对来说会比较麻烦一些。

15715
3341jaychang1989 回复

如果整套环境有非常多的后端依赖服务,不仅仅是一个webserver那么简单,尤其针对分布式的环境,不太可能在本地就能搭建起一整套环境。并且出现问题的环境的数据库跟本地的数据库也是不一样的。如果能直接在远程进行调试,是一种不错的选择。

13997
15715zni.feng 回复

倪子分析得透彻!

104 seveniruby 将本帖设为了精华贴 07月13日 19:58
10132

远程调试可以很大程度上节省本地环境搭建的成本,但是一般远程的属于公共资源,如果我们debug访问的话会导致他人无法访问,所以个人觉得还是本地调试+日志分析比较稳妥(除去两位所说的特定或复杂场景)

13997
10132haifushi 回复

不同项目情况不同吧,我之前负责的项目人比较少,一般远程debug之前在群里跟其他同事说一声就好,同时需要使用环境的情况比较少

10132
13997Tester_Ella 回复

确实是视项目而定😅

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册