Skip to content

before and after global hooks? Concurrently testing a shared state #311

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mattkrick opened this issue Dec 7, 2015 · 10 comments
Closed

Comments

@mattkrick
Copy link
Contributor

As I understand it, before and after are file-specific, meaning when the last test in that file completes, the after hook is called.

I'm doing some database testing & I have multiple test files. When all the tests complete, I'd like to drop the table. The problem is, I'm not sure which file will complete last.
If I drop the table at the end of the file A, it'll screw up tests currently running in file B, so I can't put a hook in every file.

Currently, i put those hooks in my largest test file and hope for the best.
I could create a new DB for each test file, but that seems kinda crazy.
I could also set the global serial flag, but that kills the performance boost.

Is there a better way for concurrently testing things that share state? Or alternatively maybe have tests run concurrently, but files in serial?

@BarryThePenguin
Copy link
Contributor

Can you create your table before you run AVA and clean up after running AVA? This sounds like something more suited to a task runner

@mattkrick
Copy link
Contributor Author

That's a good suggestion. Until now I've been able to do without one (just webpack + npm) but I guess that's the best choice. Thanks!

@BarryThePenguin
Copy link
Contributor

npm has pre and post scripts https://docs.npmjs.com/misc/scripts

pretest and posttest should be helpful

@mattkrick
Copy link
Contributor Author

I totally forgot those existed! Oh that's awesome, cheers!

@scottmas
Copy link

scottmas commented Jan 29, 2018

@mattkrick It would be awesome if this could be re-opened. The biggest thing is if we want to have mandatory initialization and cleanup scripts running before the tests. It's a HUGE pain.

To get a before global initialization hook (with async http requests, etc), I can do so with a --require init-script.js ava and then inside that script do a gross child_process.spawnSync to delay execution of Ava until the http requests inside the script completely finish.

And then, to get a global post execution hook, I have to some gross Bash hackery to get the exist code and the test output. I'm not proud to commit into my code base:

TEMP_OUTPUT=$(ava ./server/e2e/**/*.e2e.js --timeout 300000 2>&1); \
export TEST_EXIT_CODE=$?; export TEST_OUTPUT=$TEMP_OUTPUT; \
node post-script.js && exit $TEST_EXIT_CODE

@novemberborn
Copy link
Member

@scottmas it's pretty much impossible for AVA to synchronize before/after function hooks in their current form, hence our advocating of pretest and posttest scripts. #1366 has an intriguing suggestion for managing resources during an AVA invocation. Somebody would have to flesh out a proposal on quite how that would work, but I'd be open to that.

@scottmas
Copy link

scottmas commented Jan 31, 2018

A function hook isn't strictly necessary. What about a global before and after script file invocations? Like the existing --require option but actually waiting for the file execution to complete before continuing on. E.g. I can imagine my Ava config looking like so:

{
  "ava": {
    "globalHooks": {
        "before": "./e2e-setup.js",
        "after" : "./e2e-cleanup.js",
        "force": ["after"]
    }
  }
}

The resource approach outlined does looks amazing, but I can imagine this being way simpler to implement. What do you think?

@novemberborn
Copy link
Member

I don't think that provides enough value over wrapping AVA's invocation in a shell script, however messy that shell script may be.

@Retsam
Copy link

Retsam commented Oct 29, 2020

It makes sense that AVA can't provide this sort of hook; but I'm having a bit of trouble adapting this to my use case. I'm trying to run a process (s3rver - a local S3 mock) while running tests.

I can start and background the process in a "pretest" hook, but I can't seem to find a reliable way to kill the process in a "posttest" hook.

@novemberborn
Copy link
Member

I run tests with Firestore and Pub/Sub emulators, and those I start separately. Not perfect but gets the job done. Same in CI: launch them as the job starts.

#2478 provides a foundation for letting you hook into AVA itself, to manage resources around test runs. I haven't yet had the time to document that and to sketch it out further so it's more accessible for contributors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants