LabHub
学习 学习路径 课程

调试实战

文档和代码不一致时,信哪个

在 LabHub 中继续学习

一句话总结

在客户公司的代码中,最危险的缺陷不是抛出例外代码,而是默默地返回合理值的代码。

概念图: 不相信两者,相信观察到的行为 · 1.将规格转换为输入输出表格。 · 2. 尝试加入边界值。 · 3.区分失败的种类。

为什么需要这个?

出现故障很容易。Traceback会告诉你问题出在哪里,监控会发出警报,但没有人相信结果。

可怕的是返回200的错误。/sum?a=2&b=3这个-1返回的API状态代码正常,在仪表板上显示绿色,日志中也没有错误,几个月后会计人员说数字不正确时才发现。到那时为止,错误的值已经复制到下游系统的多个地方。

FDE在客户公司接收的代码一般处于这样的状态。原来制作的人已经辞职了,没有测试,虽然有文件,但和代码不一样。

怎么行动

当文件和代码不同时,我们应该相信什么呢?答案是不相信两者,相信观察到的行为。但是文件不会被丢弃。因为文件是唯一告诉我们“原意”的线索,代码和文件不一致的地方就是错误候选列表。

实际操作流程如下。

**1.将规格转换为输入输出表格。**在文档上用“这个输入就是这个输出”的形式写几行。如果没有在文档上,请问客户。如果没有这个表格,就没有判断什么是错误的标准。

2. 尝试加入边界值。 0、负数、一个元素、空值、缺少必填参数。缺陷大多不是平均输入,而是出现在边界处。avg如果在三个元素中正确,但在一个元素中错误,那么是写错除法中的除数了。

**3.区分失败的种类。**返回500的错误请求和返回400的错误请求是完全不同的问题。400是“你发错了”,500是“我处理后弄坏了”。如果这种区分崩溃,下游的重试逻辑就会出现故障。因为客户端将5xx视为重试对象,所以会无限次重试永远失败的请求。

**4.怀疑数据介入的地方。**代码是正确的,但输入数据中混入了一个断开的行,所以整个程序死掉的情况非常常见。规格上写着“跳过无效的行”,但代码中没有那个分支。

在现场相遇的样子

经常会有接收的配置脚本和客户的猜测一起到达,“数据好像变多了,变慢了”。打开一看,不是变慢,而是完全死了,原因不是数据变多了,而是新来的数据中混合了第一次看到的形式的行

在这里,FDE的判断会发生变化。如果删除并跳过那个行,下周会重复同样的情况。修改为按规格跳过,并让跳过的行留下日志,下次就会在1分钟内出现原因。

没有必要直接否定客户的猜测。只要把它列入验证清单并一起确认就可以了。如果在门前拒绝客户的假设,那么在下一个障碍中,他就不会告诉你观察结果。

修好后要做的事情

工作不在于找到并修复缺陷,而在于修复代码中发现的错误。因为修复了一个错误,这意味着很有可能存在其他同类错误。原来的作者不可能只犯过一次这样的错误。

所以修改后不久就做了三件事。

1. 找到所有相同的模式。 如果找到一个写错除数的地方,就打开所有相同文件的其他汇总函数。吞噬例外except: pass找到一个后,在整个存储库中搜索其形状。这项工作通常几分钟内就能完成,几乎总是能找到第二个和第三个。

2.留下捕捉那个错误的测试。不是留下证明修改后的代码正确的测试,而是留下如果修改前就会失败的测试。这种区分很重要。前者只是记录现在的状态,而后者则防止只回顾后面的内容。先写下测试,用眼睛确认测试失败后再修改,这样这种区分就会自然而然地得到遵守。

3.写下为什么到现在为止没有人知道。这个问题的答案告诉我们应该在下次改正什么。如果状态代码是200,仪表板是绿色的,那不是代码故障,而是观察故障。这意味着在计算结果错误时没有任何发现的方法,那么就需要检查值的范围的断言或下游的对比程序。

向客户报告的时候也有顺序。**是什么出了问题,从什么时候开始,影响范围到哪里,改了什么,为了不再次发生什么,加了什么。**其中人们最好奇,FDE最经常遗漏的是第三个。如果错误的值已经流入了其他系统,那么恢复它比修改代码要大得多,这个判断由客户来做。如果不知道影响范围,最好写上不知道,并提出如何确认,比默默地过去,然后在以后发现要好得多。

下次实习要做的事情

针对未经接管转让而接管的计算API,通过对比文件中记载的规格和实际运行来发现并修复四个缺陷,使错误请求发出正确的状态代码。