Raina测试学习指南Raina测试学习指南
导读
面试题
AI 测试教程
软件测试教程
🌍 知识星球
学习交流群
  • Raina测试工具集
  • Raina常用网站&工具合集
  • 小红书
  • B站
  • 作者介绍
导读
面试题
AI 测试教程
软件测试教程
🌍 知识星球
学习交流群
  • Raina测试工具集
  • Raina常用网站&工具合集
  • 小红书
  • B站
  • 作者介绍
  • 学习路线

    • 如何入门学习软件测试
    • 如何入门学习AI赋能测试
    • 接口自动化测试学习路线
  • 工具选择

    • 如何按需学习测试工具!技术
    • 抓包工具选择
    • AI工具选择
  • 工作方法

    • 测试用例设计心得分享
    • 如何定位&排查BUG
    • 如何复盘分析bug
    • 关于如何更好的进行深度测试,我的心得
    • 测试人需要掌握的5项核心竞争能力
    • 分享我坚持了很久的工作习惯
    • 建立维护可复用测试资产库
    • 建议多总结适合自己的学习方法论
    • 如何建立常见缺陷模式库
    • 如何进行测试总结!复盘
    • 如何通过项目沉淀核心能力
    • 养成复盘bug的习惯

如何定位&排查BUG

定位排查顺序

1.进行复现

2.界面/前端初步分析

3. 接口层抓包分析

4. 日志追踪分析

5. 数据层验证 (DB + 缓存)

6. 提出假设 & 针对性验证

7. 报告与跟进

第一步:进行复现

目的:尽全力找到稳定复现的方法。这是定位的基石!如果无法稳定复现,定位将极其困难

固定变量: 使用相同的账号、相同的数据、相同的环境

记录复现条件: 成功复现时的所有细节

第二步:界面/前端初步分析

目的:通过抓包工具等快速判断是否是纯前端问题(如 JS 错误、样式问题)。如果是,直接报告前端开发。如果前端无报错且 Network 显示调用了后端接口,则进入下一步

第三步:接口层抓包分析

目的:确定请求是否成功到达服务端?服务端是否正确接收和处理了请求?响应是否符合预期?

使用工具: Fiddler, Charles, 浏览器 Network Tab (F12)。

操作:

1、清除现有抓包记录。

2、执行复现 Bug 的操作步骤。

3、停止抓包,分析相关请求。

分析点:

请求:

1、请求的url是否正确

2、请求参数(字段名、数据类型、值)是否与接口文档规定的一致

响应:

3、状态码:200 OK (成功), 4xx (客户端错误), 5xx (服务端错误)

4、响应体:结构是否符合接口文档定义、关键字段的值是否正确?返回的数据量、格式是否异常?

定位结果:

1、如果请求参数错误或缺失 -> 前端问题。

2、如果状态码是 4xx 且响应中有明确错误信息 (如 Invalid token, Missing parameter 'xxx') -> 根据信息定位(前端传参问题或后端校验逻辑问题)。

3、如果状态码是 5xx -> 严重后端错误,进入日志分析阶段。

4、如果状态码是 200 但返回数据错误 -> 核心线索! 记录下错误的返回数据,这直接指向后端逻辑或数据源问题。进入日志和数据库/缓存分析阶段

案例1:用户在某个页面进行提交时,页面报错,并且无法提交成功

排查步骤:进行抓包,发现请求参数 中有一个字段 "quantity" 前端传的是字符串 "2",但接口文档要求是整数 2,

定位:为前端参数类型处理错误

案例2:商品列表页显示的价格和点进商品详情页的价格不一致。

排查步骤:抓包对比两个接口 /api/products 和 /api/products/{id} 的响应。发现列表接口返回的某个商品 price 字段是 99.9,而详情接口返回的是 109.9。

定位:后端两个接口可能查询了不同的数据源或使用了不同的计算逻辑。(根据你的预期结果就能判断是哪个接口的数据不正确,有时间的话可以继续细究出现问题的接口取的数据源是哪个)

第四步:日志追踪分析

目的:通过日志还原请求在服务端的执行路径,找到逻辑出错点、数据错误点或异常抛出的位置。

如果开发人员自定义的业务日志比较规范,其实直接通过日志排查问题是最快的,这也是我平常用得最多的方法

操作:

  • 获取权限/位置: 知道目标服务的日志存放在哪里(咨询对应开发)

  • 输入命令进入对应服务的日志文件内;比如:cd /data/service/salon-order/logs 进入order服务的日志

  • 进入到对应的服务之后,输入查看具体某一天日志的相关命令 ,比如:

tail -f 1000 salon-order.2025-03-26.0.log 实时查看最后1000行记录(最常用的)

定位相关日志:

  • 时间戳: 根据抓包中请求发生的时间戳定位日志。

  • 关键标识:

    1、TraceID / RequestID: 最有效! 分布式系统中贯穿整个请求链路的唯一ID。在抓包的请求头或响应头中(不过也要看公司开发的规范,有些开发可能不会加这个标识)

    2、通常能找到。用这个ID在日志系统中搜索,能看到该请求在所有相关服务中的完整执行路径日志。

    3、用户ID / 订单ID / 业务ID: 如果无 TraceID,用与 Bug 直接相关的业务ID搜索。

    4、接口路径 / 方法名: 搜索处理该请求的 Controller 或 Service 类名/方法名。

  • 常用命令:

tail -f salon-order.2025-03-26.0.log |grep"关键字" 实时查看包含关键字的日志

cat -n blessed-behavior.2024-04-26.0.log |grep "12343" 查看当日全部日志中某个关键字的日志

分析日志:

  • 入口/出口: 确认请求到达了哪个服务、哪个接口。

  • 关键逻辑分支: 查看代码中关键 if/else、switch 的判断条件和走向日志。

  • 关键变量值: 日志中打印的重要方法参数、中间计算结果、数据库查询条件/结果。对比这些值是否符合预期?

  • 外部调用: 调用其他服务、消息队列的结果是否成功?

  • 关键线索 - ERROR 日志 & 异常堆栈:

    1、找到 ERROR 或 WARN 级别的日志。

    2、仔细阅读异常信息 (Exception Message) 和堆栈跟踪 (Stack Trace)。 堆栈跟踪直接指向抛出异常的代码文件、类名、方法名和行号!这是定位根源的最强有力证据之一。

示例:

案例1:计算订单优惠金额不正确。

排查:查看服务层计算逻辑的 DEBUG 日志,发现日志打印了 originalPrice=100, discountRate=0.2 (20%),但下一行日志计算 discountedPrice=80 (100 * (1-0.2)) 正确。

继续看,日志显示 finalPrice = discountedPrice - couponAmount,而 couponAmount 的值是 30,导致 finalPrice=50。但预期优惠券最多抵扣 20 元。

定位:优惠券金额校验逻辑未生效,或者从数据库/缓存查询优惠券金额错误(此时需要结合数据库定位)。

案例2: (空指针异常 - NullPointerException): 用户点击某个功能按钮后页面报 500 错误

查看应用错误日志:

ERROR [http-nio-8080-exec-5] c.e.s.UserService - Failed to get user profilejava.lang.NullPointerException: Cannot invoke "com.example.model.User.getAddress()" because "user" is null at com.example.service.UserService.getUserDetail(UserService.java:45) at com.example.controller.UserController.getProfile(UserController.java:32) ... (更多调用栈)

定位:日志清晰指出在 UserService.java 文件的第 45 行,尝试调用一个 User 对象 (user) 的 getAddress() 方法,但 user 对象本身是 null。需要检查第 45 行之前获取 user 对象的逻辑为什么返回了 null(可能是数据库查询没结果,或者参数错误导致查询条件无效)

第五步:数据层验证 (DB + 缓存)

目的:确认数据在数据库和缓存中的状态,判断问题是出在数据本身(源头错误)、数据访问逻辑(SQL/缓存操作错误)还是数据一致性(DB和缓存不同步)。

数据库查询(DB)

工具/方法:Navicat或其他可视化工具、命令行

一般就是直接去对应的表里查数据,所以要对所测功能涉及的数据库很清晰,这样排查问题快些

检查点:

  • 数据存在性: 相关的记录是否存在?

  • 数据准确性: 关键字段的值是否正确?是否和接口返回的错误数据、日志中的值一致?

  • 数据状态: 状态字段(status)是否符合业务逻辑?

  • 数据关联性: 外键关联的数据是否存在?(如订单的用户ID是否有效)

  • 事务: 相关的更新操作是否成功提交?

缓存检查

工具/方法: redis-cli, Redis Desktop Manager, 缓存控制台;这里需要了解一些常用的redis命令;

  • 检查点:

    1、Key 是否存在?

    2、Value 值是什么? 是否与数据库源数据一致?是否过期(TTL)?

案例1:用户修改了收货地址,但下单时还是显示旧地址。

排查:查询 user_address 表,发现该用户最新的 is_default 地址标志确实是旧的地址ID。

定位:后端更新默认地址的逻辑可能未正确更新 is_default 标志

案例1延伸出的案例2:

如果数据库中is_default 标志已经正确更新成为新地址了,但是页面还是显示旧地址

那这里后端有可能是取缓存的内容,在更新默认地址时,只更新了数据库,没有更新缓存。所以这里还要和后端确认取值逻辑;

第六步:提出假设 & 验证

综合信息: 将前面步骤收集的所有信息(现象、请求、响应、日志、DB数据、缓存数据)整合起来。

提出假设: 基于证据,推测可能导致 Bug 的根本原因。

修改输入: 尝试不同的输入数据,看是否能规避或触发 Bug,验证边界条件。

第七步:提交bug与跟进

  1. 提交bug,主要包含以下要素:
  • Bug 标题: 简明扼要描述问题本质。

  • 环境: 复现环境。

  • 复现步骤: 清晰、最小化的步骤。

  • 预期结果 & 实际结果: 对比。

  • 定位过程与关键证据 (核心):

    a.抓包截图(请求/响应 - 突出错误参数或响应数据)。

    b.关键日志片段 (特别是 ERROR 日志和堆栈 - 脱敏后)。

    c.数据库查询结果截图(突出错误数据)。

    d.缓存查询结果截图(如果相关)。

    e.你的分析与结论 (定位到的根本原因)。

  • 沟通协作: 与开发人员讨论你的发现和分析,确认定位结果。

  • 跟进修复: 验证开发提供的修复是否真正解决了问题。进行回归测试。

最近更新: 2026/6/3 13:04
Contributors: weixin_55062269
Prev
测试用例设计心得分享
Next
如何复盘分析bug