使用 jest 的 test.each vs. looping with forEach



有什么理由让我更喜欢一种方法而不是另一种方法吗?以下是一些示例:

describe('some tests', () => {
[1, 2, 3].forEach(num => {
test(`${num}: test`, () => {
doSomeTestStuff(num)
}) 
})
// vs.
test.each([1, 2, 3])('%s: test', (num) => {
doSomeTestStuff(num)
})
})

阅读test.each语法似乎有点困难,特别是当你可以只做原生的javascript迭代来实现看似相同的效果时。拆解/设置仍然以相同的方式发生(据我所知)。

我更喜欢vanilla JSforEach版本,因为它只是JavaScript。这意味着:

你不需要
  • 特别熟悉Jest,你不需要去文档中寻找test.each到底做了什么。特别是test.each`table`形式可以以一种令人惊讶的方式表现,例如参见Jest test.each with literal table:"没有为给定的标题提供足够的参数"。
  • 同样,它在测试框架之间是可移植的,您可以在Mocha,Tap等中使用相同的方法。
  • 您可以获得适当的 IDE 支持 - 您需要等待运行时来确定'.add($a, $b)'是否真的与对象中的属性匹配,而`.add(${a}, ${b})`可以静态检查和自动完成(并随心所欲地操作,因为您可以插值任意表达式)。

测试的执行或报告方式没有任何差异,这是不正确的。forEach循环在测试发现时运行,并且所有三个测试都已注册。然后,它们都在执行时单独运行。只有在单个测试用例移动循环时,您才会看到影响其他情况的故障问题,例如:

describe('some bad tests', () => {
// this an example of how not to do it
test('num tests', () => {
[1, 2, 3].forEach(num => {
doSomeTestStuff(num)
}) 
})
})

使用原版forEach方法需要注意的另一件事是,如您所所示,内联测试用例数组是很常见的。如果您依赖 ASI,正如您的示例所示,这有时意味着您需要在数组前面加上;

describe('some tests', () => {
[1, 2, 3].forEach(num => {
test(`${num}: test`, () => {
doSomeTestStuff(num)
}) 
})
;[4, 5, 6].forEach(num => {
test(`${num}: test`, () => {
doSomeTestStuff(num)
}) 
})
})

没有这个,你会得到TypeError: Cannot read property '6' of undefined.

这可能是对Jest有利的投票,但是如果您不打算使用分号,则需要知道它们何时插入,何时不会入 -我认为这是对分号的赞成。

好问题!

从表面上看,这两者似乎基本等同,但是您可能想改用.each有几个原因。

  • 如果forEach中的预期失败,它将立即失败并停止执行。这使您对forEach中的其他测试是通过还是失败一无所知。使用.each它基本上是为数组中的每个项目编写一个单独且不同的测试。
  • 如果forEach中的预期失败,则数组中的哪个项目导致失败并不总是很明显。在.each中,您会自动从唯一的测试名称中获取上下文。
  • 借助.each,您可以使用标记模板文本轻松处理多个参数,并且随着参数的增长,.each可以非常富有表现力,并且比具有任意值的数组更具可读性。
  • 正如我之前所说,.each为每个项目创建一个单独的测试,因此最终报告会让您看起来编写的测试比实际拥有的要多。只是一件小事,当你看到最终输出时,它会带来满足感。

test.each的一个优点是更好的工具支持。我刚刚在VS Code插件orta.vscode-jest上注意到了这一点。

最新更新