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

发表于:2017-7-12 11:17

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Ella    来源:51Testing软件测试网采编

  刚工作那会,每听人讲起通过远程调试代码来定位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按钮即可。
 
  二、服务端增加指定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)。
  3、查看问题代码前后的业务逻辑
  通过代码走读可以看出,这个方法用于获取可选的续费时间段,对systemSettingService.defaultRenewDurations()进行遍历时抛了NPE。
  
  4、打断点,进行远程调试
  在PaymentRestServiceImpl.java的448行打上断点(断点位置可视具体情况而定)。
  在Intellij IDEA顶部菜单栏选择Run-> Debug 'Remote界面中指定的Name';或者在下图中间红框中选择对应Name后点击右侧的绿色图标,在下方的Console区出现如下提示语则表示已成功连上远程服务器。
  注意:本地代码分支及版本号要与远程服务端的代码一致。
  重新在续费页面输入信息点击下一步按钮时,调试程序会停留在断点处,即为下图左侧的勾号所在位置。IDEA界面下方会出现Debug视图,左下角Frames区是方法调用堆栈区,第一行显示当前程序停留的代码行,中间Variables区显示变量信息,右下角Watches区可添加观测变量。
  中间红框中为5个常用的调试按钮,从左到右分别为:
  1、step over:执行下一行,有方法调用则执行后返回,到下一行
  2、step into:执行下一行,有自定义方法则进入其中(不会进入官方类库的方法)
  3、force step into:执行下一行,任何方法都能进入
  4、step out:跳出当前方法返回被调用处的下一行
  5、drop frame:返回当前方法的调用处,即Frames区的下一行显示的代码处
  在右下角Watches中添加观测变量systemSettingService.defaultRenewDurations(),值为NPE。点击step into按钮进入该方法中,可以看出,该方法要返回续费时的可选时间段getRenewDurations,但代码逻辑却以购买的可选时间段getPurchaseDurations非空作为判断条件,但为什么抛NPE呢?查询redis中对应的配置项信息,发现配置项中只有购买的可选时间段,没有续费的可选时间段,所以正好符合代码中的非空判断,所以返回了NPE。到这里就可以确定问题代码的根源了。
 
  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直接进行远程调试去排查问题还是很适用的。而且随着对项目代码的理解程度的加深,定位问题的速度会越来越快。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号