bug 抓到之后怎么处理?三步曲:复现(稳定重现才能定位)、定位(print 到调试器)、管理(进 bug 跟踪系统 BTS,记录生命周期)。核心心法:修不了的 bug 都是没有稳定复现步骤的 bug。
上一节:等价划分与边值分析 | 下一节:检查、静态分析与软件指标
一、复现是第一优先级
【有时候会崩】【偶尔卡一下】这种报告无法开工。先问三个 W:什么操作(What)、什么环境(Where)、什么频率(When)。把复现步骤缩到最小:两步能触发就不用五步——最小复现本身就是半个答案(它把噪音剥掉了)。
二、定位三件套:print、断点、调试器
- print 大法:最朴素——在嫌疑处打印变量值。快,但改完代码要删,多则乱。
- 断点(breakpoint):让程序在指定行暂停,所有变量原样可查。
- 调试器:断点+单步执行(step over 走过、step into 进函数)+变量面板+调用栈查看。Python 自带
pdb,VS Code 里按 F5 即图形化调试。开调试器走一遍程序的执行路径,胜过盯着代码猜十分钟。
4-7 讲过递归的调用栈——调试器里【调用栈】面板就是把栈展开给你看:哪层调用进入哪层,一目了然。
三、BTS:bug 的一生
BTS(Bug Tracking System,bug 跟踪系统)让每个 bug 有档案:标题、复现步骤、环境、严重度、指派给谁、当前状态。生命周期大致是:
新建(new) -> 已确认(ack) -> 修复中(fix) -> 待验证(resolved) -> 关闭(closed)
\________ 验证不过,重新打开(reopen) ________/
reopen 是 BTS 的灵魂:修过的 bug 验证不通过,必须打回去而不是关掉。常见工具:GitHub Issues、Jira、GitLab Issues——本质都是带状态的清单。
修复后的回归测试:修 bug 前先写复现测试(5-3 讲过),修好变绿后永远留在测试集里——这个 bug 从此不可能无声回归。
四、动手 Demo:一次最小复现与二分定位
# 报障:偶发算错平均分。先做最小复现。
def average(scores):
return sum(scores) / len(scores)
# 嫌疑数据:正常 / 空列表 / 带非数字
print(average([80, 90, 100])) # 90.0 正常
try:
print(average([])) # 复现成功!稳定报错
except ZeroDivisionError as e:
print("复现:", type(e).__name__)
# 二分定位:在可疑链路上逐段打印
def average_debug(scores):
print(" [1] 入参 =", scores)
total = sum(scores)
print(" [2] 合计 =", total)
count = len(scores)
print(" [3] 个数 =", count)
return total / count
average_debug([80, 90, 100])
沙箱实跑输出:
90.0
复现: ZeroDivisionError
[1] 入参 = [80, 90, 100]
[2] 合计 = 270
[3] 个数 = 3
看到什么算成功:空列表稳定复现 ZeroDivisionError;print 链路三段全正常。
读结果:入参、合计都对,个数是 0——除零的定位只用了三行打印。正式修法:if not scores: return None(或抛带说明的异常),并配一个 test_average_empty 留守(5-3 的规矩)。
五、30 秒实验
给 average 加上空列表保护后,把 average([]) 的期望值写进断言——这段代码就是将来 BTS 里那条 bug 的【结案证据】。
六、常见误区
| 误区 | 真相 |
|---|---|
| 【偶尔出现】就先放着 | 不稳定复现的 bug 永远修不了;先花功夫让复现稳定 |
| print 挂满整个文件 | print 是速效药不是处方;调试器可随时暂停随时看,不留残渣 |
| 修好就关单 | 必须验证+回归测试留守;验证不过就 reopen |
自测三问(点击展开)
1. **为什么复现排第一?** 答:不能稳定复现就无法确认修复有效;最小复现还自带定位信息。 2. **调试器比 print 强在哪?** 答:不修改代码即可暂停、单步、查全部变量和调用栈,零残渣。 3. **BTS 里 reopen 意味着什么?** 答:修复验证不通过打回重修——防止把未修好的 bug 关进棺材。- ☐ 5-7 学习完成
相关笔记
- 递归与尾递归 —— 调用栈面板的经典现场
- 单元测试与集成测试 —— 修 bug 前先写复现测试
- ⌨️ 编程原理 · 索引 —— 全课路线图