Ava: Add test.each() to support BDD

Created on 5 Mar 2017  路  10Comments  路  Source: avajs/ava

This will help to support usage such as:

test.beforeEach(t => {
  t.context.game = new Game()
})

test.each(
[
  { c1: 1, c2: 2, dir: 'west' },
  { c1: 2, c2: 3, dir: 'south' },
  { c1: 3, c2: 4, dir: 'east' },
  { c1: 4, c2: 5, dir: 'north' }
], t => {
  const { game, c1, c2, dir } = t.context
  game.createAndConnectCaverns(c1, c2, dir)
  const p = game.createPlayerIn(c1)
  p.move(dir)
  t.is(p.location, c2)
})

Most helpful comment

Interesting. This is currently possible using macros:

const playerIsAtLocation = (t, c1, c2, dir) => {
  const { game } = t.context
  const p = game.createPlayerIn(c1)
  p.move(dir)
  t.is(p.location, c2)
}

for (const {c1, c2, dir} of [
  { c1: 1, c2: 2, dir: 'west' },
  { c1: 2, c2: 3, dir: 'south' },
  { c1: 3, c2: 4, dir: 'east' },
  { c1: 4, c2: 5, dir: 'north' }
]) {
  test(playerIsAtLocation, c1, c2, dir)
}

There's something nice about your test.each() suggestion but I'm not sure it's worth the maintenance cost.

All 10 comments

Interesting. This is currently possible using macros:

const playerIsAtLocation = (t, c1, c2, dir) => {
  const { game } = t.context
  const p = game.createPlayerIn(c1)
  p.move(dir)
  t.is(p.location, c2)
}

for (const {c1, c2, dir} of [
  { c1: 1, c2: 2, dir: 'west' },
  { c1: 2, c2: 3, dir: 'south' },
  { c1: 3, c2: 4, dir: 'east' },
  { c1: 4, c2: 5, dir: 'north' }
]) {
  test(playerIsAtLocation, c1, c2, dir)
}

There's something nice about your test.each() suggestion but I'm not sure it's worth the maintenance cost.

Thanks.
I'm thinking of this in the context of BDD, and IMO the benefit of test.each() over macros is that the cases are included within the test.

Speaking of each, with the power to power-assert and magic assert, do you think it is possible to generate a markdown spec doc from the JS file?

UPDATE: this is just an idea. An alternative is to provide functions allowing ava to be hooked into BDD system such as shouldit

I'm thinking of this in the context of BDD, and IMO the benefit of test.each() over macros is that the cases are included within the test.

UPDATE: this is just an idea. An alternative is to provide functions allowing ava to be hooked into BDD system such as shouldit

We're happy to see alternative interfaces built on top of AVA's current interface. I'm not convinced we need additional functionality for that though.

Speaking of each, with the power to power-assert and magic assert, do you think it is possible to generate a markdown spec doc from the JS file?

Possibly using the TAP output, but that doesn't include the diffs. We'd be happy to land a PR for that if there's a standard way of expressing it in TAP.

Thank again.

After some more thoughts, it does seem like just relying on ava to do this is not sufficient.
A layer on top of it is much more desirable.

The BDD system I envision is not the BDD syntax in JS test framework such as in mocha, but a system that actually allows Business Analyst, Product Manager, QA, to write acceptance test that they can reason about (similar to fitNesse).

These tests can be wired up to the actual tests in ava to determine if they pass or fail.

This means the system need to understand before, beforeEach, after, and afterEach code and reuse them.

One thing that is "lacking" is the ability to nest test.
On the other hand, my understanding is that ava choose to not do nesting.

One thing that is "lacking" is the ability to nest test.

Yes, see #222. That said, libraries can implement their own nesting on top of AVA's interface. I did something similar, see https://github.com/avajs/ava/issues/222#issuecomment-248631231.

I'll close this now. Thanks for your input!

Apologies for joining a dead thread; I came looking through the issues for any other discussions about parameterized/data-driven test support in Ava. I found lots of discussion in various tickets, but this seemed the most recent and most directly related to my search so I wanted to add an extra voice to the conversation.

The current macro capability is great, but I do agree it would be even nicer if we could just insert parameters into the test function directly as @unional described. I've seen several examples of something similar done for Mocha to simplify its dynamic tests:

https://github.com/mikejsdev/mocha-param

And for QUnit:

https://github.com/AStepaniuk/qunit-parameterize

And another more generic library for multiple test frameworks:

https://github.com/lawrencec/Unroll/blob/master/examples/ava/ava-example.js

And one going in a different direction to emulate TestNG decorators:

https://github.com/alsatian-test/alsatian

It's definitely a common use case for easier test design. As you said, you've provided other ways to accomplish this so maybe we don't strictly need it, but it would be a very nice to have.

In any event, thank you again for all the great work done on Ava.

I've seen several examples of something similar done for Mocha to simplify its dynamic tests

These build on top of Mocha though. A similar module can be built on top of AVA.

True. I listed examples across several frameworks to show that it's very much a common need.

As you noted, it's such a common need that there exists, to some extent, modules for many of the popular JS frameworks to accomplish such a thing, but it means yet another dependency to rely on and third party implementations might never be as clean or pleasant to use as Ava supporting it directly.

Coming from other languages (Java/C# specifically) I've found it strange that many JS frameworks don't nicely support this kind of testing out of the box. It would be another stand out feature of Ava, in my opinion.

Maybe, once AVA has matured. Changing the test interface is not a priority at the moment.

Was this page helpful?
0 / 5 - 0 ratings