我已经把这篇博文作为一个演讲,你可以在这里观看。
不久前,Guillermo Rauch(Socket.io的创建者和Zeit.co的创始人(该公司是最近出现的许多很棒的东西背后的公司))在推特上发表了一些深刻的观点。
这很深,尽管很短,所以让我们深入了解一下。
编写测试
是的,对于大多数项目,你应该写自动测试。如果你重视你的时间,你就应该这样做。从测试中抓到一个bug,要比在凌晨2点接到电话,然后修复它要好得多。**通常我发现当我花时间写测试时,我可以节省时间。**实现我正在构建的东西可能需要或不需要更长的时间,但我(和其他人)几乎肯定会节省维护它的时间。
在编写测试时,你应该考虑的是它们能给你带来多大的信心,使你的项目没有bug。像TypeScript和ESLint这样的静态类型和标记工具可以给你带来很大的信心,如果你没有使用这些工具,我强烈建议你去看看它们。也就是说,**即使是强类型的语言也应该有测试。**类型和提示不能确保你的业务逻辑没有错误。因此,你仍然可以通过一个好的测试套件来严重增加你的信心。
不要太多
我听说经理和团队强制要求对应用程序进行100%的代码覆盖。 这确实是个坏主意。问题是,当覆盖率超过70%时,你的测试的回报就会越来越少(这个数字是我编的......没有科学依据)。为什么会这样呢?当你一直追求100%的覆盖率时,你会发现自己花时间去测试那些真正不需要测试的东西,那些根本就没有逻辑的东西(所以任何错误都可以被ESLint和Flow发现)。维护这样的测试实际上真的拖累了你和你的团队。
你也可能发现自己在测试实现细节,只是为了确保你能得到那一行在测试环境中很难重现的代码。你真的想避免测试实现细节,因为它不能给你很大的信心,你的应用程序是工作的,而且它在重构时拖慢了你。当你重构代码时,你应该很少需要改变测试。
我应该提到,我所有的开源项目几乎都有100%的代码覆盖率。这是因为我的大多数开源项目都是较小的库和工具,在很多不同的情况下都可以重用(在很多消耗性项目中,一个破损可能会导致一个严重的问题),无论如何,它们都比较容易获得100%的代码覆盖率。
主要是集成
有各种不同类型的测试(请看我在Fluent Conf会议上的5分钟演讲:"我们能从车轮上学到的测试")。 它们各自都有取舍。当我们谈论自动化测试时,我们所谈论的三种最常见的测试形式是。单元,集成,和端到端。
这是我的前端大师工作坊的一张幻灯片:"测试JavaScript应用程序"。

这个测试金字塔是我从Martin Fowler的博客和Google测试博客中得到的一个组合。
如图所示,该金字塔从下到上显示。随着你在金字塔上的移动,测试的编写/运行速度越来越慢,运行/维护的成本越来越高(在时间和资源方面)。这意味着,由于这些因素,你应该把更多的时间花在单元测试上。
但它没有显示的一点是,**随着你在金字塔上的移动,每种形式的测试的置信度都在增加。**你会得到更多的回报。因此,虽然E2E测试可能比单元测试更慢,更昂贵,但它们给你带来了更多的信心,你的应用程序正在按计划工作。
如前所述,我们的工具已经超越了马丁最初的测试金字塔概念中的假设。这就是为什么我创造了 "测试奖杯"🏆。
这里有一个关于集成测试重要性的另一个幽默的说明。
如果你的组件<A /> 用道具c 和d 来渲染组件<B /> ,这并不重要,因为如果不提供道具e ,组件<B /> 实际上就会损坏。因此,虽然有一些单元测试来验证这些部件的独立工作并不是一件坏事,但*如果你不同时验证它们是否能正常工作,那就没有任何好处。*你会发现,通过测试它们在一起正常工作,你往往不需要费力地去测试它们。
**集成测试在信心和速度/成本的权衡上取得了很大的平衡。**这就是为什么建议你把大部分(不是全部,注意)精力花在这里。
关于这一点,请阅读测试实施细节。更多关于测试的不同区别,请阅读Static vs Unit vs Integration vs E2E Testing for Frontend Apps。
如何编写更多的集成测试
集成测试和单元测试之间的界限有点模糊。不管怎么说,我认为要写更多的集成测试,最大的事情是停止模拟这么多东西。当你模拟一些东西时,你就会消除对你所测试的东西和被模拟的东西之间的集成的所有信心。我理解,有时候这也是没办法的事(尽管有些人不同意)。你并不希望每次测试都发送邮件或从信用卡上扣钱,但大多数时候你可以避免模拟,这样做会更好。
如果你在做React,那么这包括浅层渲染。关于这一点,请阅读Why I Never Use Shallow Rendering。
总结
我认为没有人会认为测试软件是浪费时间的。 最大的挑战是知道要测试什么,以及如何以一种真正有信心的方式来测试它,而不是测试实现细节的虚假信心。
我希望这对你有帮助,我祝愿你在实现你的目标中找到运载应用程序的信心!