• 测试不是全部 但最重要
  • 发布于 2个月前
  • 230 热度
    0 评论
最近我一直在思考的一个话题是加里·伯恩哈特所谓的“ 意识形态”。如果你愿意,我强烈建议你现在就去看看,我会在这里等。另外,这里是文章的摘要:动态类型爱好者喜欢说他们不需要编译器,因为他们有测试; 静态类型爱好者喜欢说他们不需要测试,因为他们有编译器。

就我的经验而言,前者说法比后者更普遍常见,很少听到喜欢静态类型的人说他们不需要进行单元测试。也许在过去,情况有所不同; 在历史的某个时刻,谷歌工程师声称单元测试只对糟糕的程序员来说才是必要的,他们已被证明是错误的,现在谷歌严肃地执行所有代码的测试。

我有时听到Node.js,Python或Ruby等语言爱好者说,他们并不真正需要编译器提供的安全性和结构,因为他们有单元测试套件来捕获bug。

这是一种有害的哲学。在某些情况下,当错误并不重要时,这并不会很糟糕:在早期创业公司中,错误的影响有限,因为您根本没有客户,或者客户可以容忍问题。此外,你能负担得起漏洞,因为快速升级和改变产品的利润超过了修补bug的成本。
不幸的是,随着初创公司的发展,这种情况会发生变化,而错误的代码和回归错误会直接导致客户流失。这很复杂,因为随着软件复杂性的增加和团队规模的扩大,造成错误的可能性会迅速增加。除非你对此采取行动,否则团队最终只是在灭火而不是制造产品的位置。

“但如果你有一个好的测试套件,这不会发生!” 很多开发者这样声称。如果测试不够好,他们在能找出我的错误吗?错误有很多方式可以通过测试,这里有一些例子。我在专业环境中遇到过其中的每一种,包括有非常严格的编码标准的Google:
没有测试任何东西的测试。测试可以执行代码并获得100%的代码覆盖率,但如果它没有检查正确的条件,那么它不是一个好的测试。
没有人写过它们。有时当修复某些东西有压力时,人们会跳过编写测试的过程。许多公司都有一种关注尽快上市的文化,这不利于编写可靠的软件。
不检查重要案例。我曾看到只检查快乐路径的测试,没有检查任何错误的情况 - 如果你无法连接到数据库,或连接丢失怎么办?如果您尝试阅读的文件不存在怎么办?
集成/功能测试。就其性质而言,集成测试更难以编写和维护,并且输入的组合以指数方式爆炸,因此在绝对关键的项目之外拥有可靠的集成测试套件是非常罕见的。
在推送之前没有人运行测试或查看结果。这种情况发生在没有任何进程的设置中(我正在看你,启动黑客),其中失败的测试会阻止提交/合并/推送。
这里有一些解决方案。有些非常容易和普遍:代码审查,持续集成,预先挂钩和主分支上的严格权限只是少数几个。

一个减少很多麻烦的更深层次的解决方案是使用某种类型的提示。我推荐这个的原因是,如果你一直使用它,它会从等式中消除很多人为错误 - 编译器将始终记得检查所有内容,即使是最好的人类偶尔会滑倒并忘记某些东西。编译器在查找错误方面也要快得多,运行集成测试套件可能需要很长时间 - 根据经验,我不会阻止集成测试的提交,否则可能需要数小时才能进行更改。它也是自动的:你不必编写测试。在我的书中,少工作是一件好事。

但是,我是否必须使用其中一种令人烦恼的语言(如C ++或Java)来实现这一点?花所有时间来尝试满足编译器而不是真正的工作?不!您可以在带有TypeScript或Google的Closure编译器的Node.js中使用它,在Python中您可以使用Python 3的类型声明,而在Ruby中您可以使用类似RDL(免责声明,我从未使用过它)。还有现代静态类型的语言,如Go,Rust,Swift和Kotlin,它们比前几代使用起来更舒适。

对于不同系统之间的通信,您可以将JSON与JSON Schema或Protocol Buffers一起使用(如果需要,可以将其序列化为JSON)。过去有个恐怖故事:我的团队正在使用Node.js和Python构建分布式系统,系统中的不同节点将通过JSON传递消息。有人对一个系统进行了更改,改变了其中一个消息中字段的类型,但在实际尝试访问该字段之前有几个跃点。尝试访问它的系统显然已经崩溃,并且追踪该字段被修改的位置需要相当多的侦探工作(除了导致生产中断)。

幸运的是,崩溃发生在Python系统中,所以我们有一个KeyError和堆栈跟踪,至少知道发生了什么,如果它发生在一个Node.js系统中它会产生undefined并能继续运行。如果我们对消息使用了某种类型的检查,那么这个调试练习就会简单得多。

我强烈建议,如果您正在进行任何类型的后端或基础架构开发,并且您尚未使用上面提到的测试方法,那么您该开始使用了。它会在以后为您节省一些麻烦。

用户评论