从程序员的测试说起

对于程序员来说,我们的第一反应是“测试软件功能应该是 QA 干的活”,实际上我们平时的软件开发中有大量的时间,就是在干“测试”。

所谓的”测试“,可以分为两个部分,一部分是验证功能有没有问题,在我们平时的开发流程中,多数表现为,“写一段代码,就跑一下打开控制台或者浏览器简单操作下,看看有啥问题”,另一部分是出现问题时进行定位,”比如打开浏览器控制台进行 debug 操作“。 ** 可以说,我们只要在开发,其实就是在“测试”与“编码”之间无限循环,“测试”是如此重要,重要到它贯穿了我们整个软件开发过程。我们需要非常高效地实现它们。那么“无计划的手动验证”与“手动的启发式定位”都是无法容忍的低效手段,必须将它们替换为“有计划的自动化验证测试”和“有计划的逐模块自动化排查”。

最近有一个很火的概念叫 vibe coding,基本流程是:

  1. 给 ai 一个需求,让其完成(之前是手动写)
  2. 按需 accept 变更后,直接执行
  3. 把控制台中的报错信息重新告诉 ai 并修复(之前是手动 debug)
  4. 循环往复进行下一个需求

这个流程看上去是自动化,其实它只是更高频次的手动验证与定位,ai 并不能理解 bug 产生的原因,仅仅是按照控制台信息,去套用可能的方案。这和我们平时在那些令人头大的遗留代码中解决问题,需要时不时改几行试着看看效果是一样的。现实中这种模式即然在屎上堆屎,造成大量预期外的问题,我们自然也不能指望同样工作模式下的 ai 能给我们解决问题(实际上 ai 产屎更快了)。

TDD 下的公式解释器设计

现在我们有这么一个需求,我给你字符串“SUM(1,2)“,需要解析这个字符串并计算出结果为 3。现在我们不知道怎么写,中间要如何解析,有什么其它场景也不知道。我们可以通过一个简单的 spike,进行快速的思想验证。那么最快速的案例就是下面这样

describe('spike', () => {
  it('should ', () => {
    expect(new Calculator().calculate('SUM(1,2)')).toBe(3)
  });
})
 
class Calculator {
  calculate(formula: string) {
    return formula
  }
}