Run code before and after a group of test files
See original GitHub issueDescription
The before and after hooks are really useful, but they are limited to a given file.
When doing integration test we often have to do some relatively long set up tasks such as starting a database, a server or a docker container. As those tasks take often several dozen of seconds or a few minutes, we want to do them only once per test run.
As before
and after
are limited to the file in which they are defined, it forces us to write all the integration tests in the same file. This is not ideal as it ends up creating a giant file that is difficult to maintain.
So it would be great to be able to define have a special before
and after
hook that spans a group of file.
I’m not really sure what would be the best API, but I can think of two solutions.
t.beforeAll(scope, [function])
and t.afterAll(scope, [function])
Those special version of beforeAll
and afterAll
could be defined in any test file (even by themselves without other tests) and the function
is optional.
All the test files that have a beforeAll
or an afterAll
for a given scope
would have to be run only after the function
of all the beforeAll
of the same scope
ran. And it will run the function
of all afterAll
only when the files having the same scope
are completed.
// integration/mocks.js
test.beforeAll('database', async () => {
await startDatabase();
});
test.beforeAll.always('database', async () => {
await stopDatabase();
});
// integration/scenario1.js
test.beforeAll('database')
test.serial('First step of scenario 1' async t => {
// Do something with the database
}
test.serial('Second step of scenario 1' async t => {
// Do something else with the database
}
test.beforeAll.always('database');
// integration/scenario2.js
test.beforeAll('database')
test.serial('First step of scenario 2' async t => {
// Do something with the database
}
test.serial('Second step of scenario 2' async t => {
// Do something else with the database
}
test.beforeAll.always('database');
after.js
and before.js
in a diretory:
.
+-- test/
| +-- integration
| +-- before.js
| +-- scenario1.js
| +-- scenario2.js
| +-- scenario3.js
| +-- after.js
ava
would run before.js
, then all the tests in scenario1.js
, scenario2.js
, scenario3.jsthe same way it does now (in parralel or serially is
.serialis used) then run
after.js`.
In other word, ava
would guarantee that the files scenario1.js
, scenario2.js
, scenario3.jsare run only once
before.jsresolves and that
after.jsis called only when all the tests in
scenario1.js,
scenario2.js, scenario3.js
are completed.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:6
- Comments:9 (4 by maintainers)
That would be possible but that would make it impossible to use
ava
directly during development, for example to select which test to run during withava <files_to_test>
.I found a workaround that kind of works in the current version:
With the following:
On
ava -v
I obtain:if I use
t.test.serial
it also work as expected.The problem is that if define
t.before
,t.after
,t.beforeEach
ort.afterEach
hooks they are executed within the context ofindex.test.js
. That mean at.beforeEach
defined inscenario-1.test.js
will be executed before each test in bothscenario-1.test.js
andscenario-2.test.js
. But as long as all the scenario share the samet.before
,t.after
,t.beforeEach
ort.afterEach
hooks its ok.So, yes there is workarounds that are not too bad. But having such feature in the core would still be nice, even in a simpler than what I proposed.
But feel free to close if you think the improvement of having that in the core vs a workaround doesn’t worth the effort/extra code/extra maintenance.
It’s definitely something Ava should have