发布于 2026-01-06 1 阅读
0

单元测试不应该出现在你的代码评估中!DEV 的全球展示挑战赛由 Mux 呈现:展示你的项目!

单元测试不应该包含在你的代码评估中

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

我在这个问题上保持沉默太久了。但现在我要开始说了。系好安全带……

过去几周,我在代码评估过程中遇到了一些单元测试方面的问题,让我感到既恼火又愤怒。这并非我第一次遇到这类问题。但我终于忍无可忍,要大声疾呼:

在你们强加给应聘者的编程评估中,单元测试不应该占有一席之地。


对你们中的一些人来说,这听起来可能像是异端邪说。(提示:我不在乎。)但如果这件事真的让你如此困扰,那么很有可能你本身就是问题的一部分。


图片描述

我不是异教徒

在详细解释为什么单元测试不应该出现在代码评估中之前我想先声明,我并非反对单元测试本身。当然,你应该在开发环境中使用单元测试。当然,大量的单元测试可以极大地提高代码质量。当然,你也希望所有开发人员都能熟练地使用单元测试。

所以,你当然应该把它纳入你所有的编程评估中……对吧?

不。

请允许我解释一下……


图片描述

编写测试题既浪费时间,也可能对考生不尊重。

在日常开发环境中,如果有人说“我完成了这项任务并提交了,但我没有编写任何单元测试,因为我时间不够”,这通常是不可接受的。在正常的“开发操作”中,只有经过适当的测试,任务才算真正完成。但这条标准不应适用于代码评估。

大多数代码评估都有时间限制。它们会给出一个规定的时间期限,要求你在期限内修复一个 bug、开发一个新功能或以某种方式修改现有功能。通常,即使对于资深开发人员来说,这些时间限制也会让人感到畏惧。

想象一下,你有一个小时的时间用 React 开发一个功能。也许这并不。也许你信心满满,觉得肯定能搞定。但在开发过程中,你遇到了一个bug。你知道的……就是那种让你愣在那里好几分钟,然后纳闷“等等……这到底是怎么回事 ”的 bug。也许你忘了连接一个关键帧,需要花点时间才能意识到自己忽略了什么。也许你只是犯了一个愚蠢的拼写错误,在 IDE 里根本看不出来。总之,重点是,即使是最简单的任务,有时你也会因为犯错而浪费 10 到 15 分钟来纠正错误。

最终,你解决了这个问题。然后,你在截止时间前一小时完成了整个功能。事实上,你做得非常出色。你对自己写出的代码相当有信心。

但你没有时间添加任何测试……

如果你的代码很扎实,你完成了任务,并且展现了对 React 的扎实理解,那么你绝对不应该仅仅因为没有时间给你的解决方案添加单元测试而被扣分(或被淘汰

让我把话说清楚。编写单元测试本身通常非常简单。大多数测试框架的语法都非常相似,它们的设计目的就是帮助你以语义清晰的方式编写测试。它们使用的措辞类似:



it('Should enqueue the items to the queue', (done) => {...});


Enter fullscreen mode Exit fullscreen mode



onDequeueSpy.calledOnce.should.be.true;


Enter fullscreen mode Exit fullscreen mode

因此,对于任何经验丰富的开发人员来说,以这种方式编写测试应该感觉相当自然。

即使单元测试在语法上可以做到不言自明,但要编写真正有意义且能妥善处理各种极端情况的单元测试,仍然需要一些技巧(而技巧就意味着时间)。在正常的开发周期中,实现这些测试所需的时间不应该成为负担。但如果你正面临代码评估的倒计时,那它绝对会成为一种负担。

几周前,我完成了一项编程测试,他们要求我在一个现有的 React 代码库中添加大量功能。他们告诉我,所有工作都必须在 45 分钟内完成。这不仅意味着我要添加新的组件并连接所有事件处理程序,还必须确保所有代码都与代码库中已有的风格完全一致。此外,还有许多 CSS 要求,精确地规定了解决方案的外观。所以,仅仅实现逻辑是不够的,我还必须让所有内容都符合设计规范。而且,所有这些都必须在 45 分钟内完成。

当然,这还不是他们想要的全部。需求还要求所有现有测试都必须通过,而且每新增一个功能,我都要编写新的测试。所有这些都得在45分钟内完成。这简直荒谬至极。

如果我已经编写出了一个功能齐全、满足任务要求的解决方案,但我没有时间为我的新功能编写合适的单元测试,而你仍然想把我排除在外,那么……很好。相信我,反正我也不想在你那糟糕的开发团队里工作。

但这些并非编程挑战中单元测试的唯一问题……


图片描述

测试失败

所以,也许你并不是要我编写测试。也许你的代码库里有一堆单元测试,需要我先通过这些测试才能提交我的解决方案?听起来合情合理,对吧

出色地...

我多次打开一个新的代码库,需要在其中编写一些新的解决方案,结果发现测试根本无法通过当然,如果“测试”的目的是为了检查代码库中是否存在 bug,而单元测试失败正是因为这个 bug,现在你们又想让我修复这个 bug,那么……好吧,我明白了。

但我遇到过好几次这样的情况:我本应该开发全新的功能,但当我打开代码库并运行那些仅用于验证旧功能的测试时,测试却失败了。于是,我不得不花费宝贵的评估时间的前15分钟来研究如何修复基础功能的测试,甚至还没来得及编写新方案的一行代码。

如果你想用这种方式考验我,那我反正也不想加入你那糟糕的开发团队。


图片描述

秘密要求

这是我遇到的另一个<sarcasm>令人头疼的问题,都是因为你的嵌入式单元测试:你并没有要求我编写新的单元测试,但却在代码库中加载了一大堆测试,这些测试旨在检验我开发的新功能是否符合规范。于是我仔细阅读了所有说明,并编写了一个满足所有要求的解决方案,它在浏览器中运行完美,但是当我运行测试时……</sarcasm>

他们失败了。

然后我又回去仔细阅读了一遍所有说明,比第一次更加认真。结果——你猜怎么着——我明明完全按照说明操作了但单元测试仍然失败。

我该如何解决这个问题?嗯,我得打开单元测试文件,从失败的地方开始反向排查,试图找出为什么我明明遵循了指令的解决方案仍然无法通过单元测试。这时我才意识到,单元测试中包含了一些隐藏的要求

例如,我昨天就遇到了这种情况。这个 React 任务有很多功能需要根据条件显示。比如,当 API 没有返回任何结果时,应该显示“未找到结果”的提示<div>。但如果 API 实际上返回了结果,则该 div 元素不应该显示。我已经按照这个要求编写了代码,但测试仍然失败了。

为什么测试失败了?因为测试非常具体地要求“无结果”的值<div> 必须为 NULL。我编写的代码使用了 ` --null` display: none。最初的要求只是说不<div>应该显示`--null` ,并没有说结果<div>必须为 NULL。所以为了让测试通过,我不得不回到我的解决方案(那个完全符合书面说明的解决方案),修改逻辑,让它输出NULL`--null` <div>

我还必须对其他几个具有类似逻辑的元素执行相同的操作。因为这些元素也有自己的单元测试——这些测试都期望一个明确的值NULL

如果说明书里明确说明了这一点,我一开始就会那样写。但说明书里从未提及。所以我不得不浪费宝贵的编程测试时间去重构我的代码。我之所以这么做,是因为单元测试中包含了一些事实上的“隐藏要求”。

如果你连确保编程挑战中的单元测试不包含秘密要求都不愿意费心,那我绝对不想加入你那糟糕的开发团队。


图片描述

不合逻辑的单元测试

也许你并没有要求我编写新的单元测试,也许你也没有在单元测试中隐藏“秘密要求”,也许所有与遗留代码相关的测试都能直接运行良好。所以,我遵守这些要求应该没什么问题

嗯……

昨天我用 Node 写一个异步队列,遇到了一系列单元测试间歇性失败的问题。这些失败是因为单元测试中队列检查的时间间隔设置得非常短。有时候所有测试都通过,有时候一两个测试失败。基本上,结果完全随机。

当然,解决此问题的一个简单方法是给这些调用留出更多时间。但是您无法更新测试文件。如果您尝试这样做,您的git push操作将被阻止。

我花了很长时间研究这个问题,试图在不修改测试文件的情况下让它稳定运行,但始终没有成功。

在同样的练习中,我遇到了一系列测试,如果你以某种特定方式编写队列暂停功能,这些测试就会失败。但如果你以完全不同的方式编写,它们就能通过。当然……他们根本没有提到他们想要的(隐藏的)编写暂停功能的方式。所以你只能在测试失败后通过反复试验来摸索。

当然,这些单元测试写得多么糟糕并不重要。对评估者来说,唯一重要的是这些(不合逻辑的)测试没有通过。

最后,我觉得他们用这些不合逻辑的测试也算是件好事,因为你猜怎么着?反正我也不想跟他们那群废物开发员一起工作。但我还是气得要死,昨天我浪费了好几个小时做他们的挑战题,之前我已经跟他们进行了一次很棒的现场面试,而且我已经写出了一个能用的解决方案,就因为他们懒得写逻辑严密的单元测试。

文章来源:https://dev.to/bytebodger/unit-tests-should-not-be-in-your-coding-evaluations-1a7