使用 jest 的 test.each 与使用 forEach 循环

Mik*_*ike 7 javascript jestjs

有没有理由我更喜欢一种方法而不是另一种方法?这里有些例子:

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

  // vs.

  test.each([1, 2, 3])('%s: test', (num) => {
    doSomeTestStuff(num)
  })
})
Run Code Online (Sandbox Code Playgroud)

阅读test.each语法似乎有点困难,尤其是当您可以只执行本机 javascript 迭代来实现似乎相同的效果时。拆卸/设置仍然以相同的方式发生(据我所知)。

jon*_*rpe 5

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

  • 您不需要专门熟悉 Jest,也不需要在文档中查找其具体用途test.each。该test.each`table`表单的行为方式尤其令人惊讶,请参见例如Jest test.each 与文字表:“没有为给定标题提供足够的参数”
  • 同样,它在测试框架之间是可移植的,您可以在 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)
    }) 
  })
})
Run Code Online (Sandbox Code Playgroud)

使用普通方法需要注意的另一件事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)
    }) 
  })
})
Run Code Online (Sandbox Code Playgroud)

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

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


Sco*_*ton 2

好问题!

从表面上看,这两者基本上是等效的,但有几个原因可能导致您想要使用它.each

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

  • 该答案中的第一条和第四条不准确。`forEach` 完成,注册所有三个测试,然后执行它们。它们是单独的测试,将单独执行和报告。如果循环位于测试用例内部,则失败只会停止其余用例。对于第二个注释,OP 也在“forEach”中设置唯一的名称。 (8认同)