Skip to content
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

Change testEnvironment on a per test basis #2587

Closed
danieldiekmeier opened this issue Jan 13, 2017 · 23 comments · Fixed by #2859
Closed

Change testEnvironment on a per test basis #2587

danieldiekmeier opened this issue Jan 13, 2017 · 23 comments · Fixed by #2859

Comments

@danieldiekmeier
Copy link

Do you want to request a feature or report a bug?

Feature

What is the current behavior?

At the moment, I can set the testEnvironment to either node or jsdom in package.json.

My exact problem is that I have a few tests that use Knex, which in turn uses node-uuid, which outputs a console.warn if window exists, but window.crypto is not available.

See also this issue on jsdom: jsdom/jsdom#1612

The console.warns are not that bad (just annoying), but I can imagine that other modules may have wildly different behaviours for running in node or jsdom, which may lead to obscure bugs.

console.warn node_modules/node-uuid/uuid.js:48
      [SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()

What is the expected behavior?

Allow every test file to overwrite the setting in package.json. If I understand correctly, every test is run separately, anyways, so this should help?

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.

yarn 0.17.10,
macOS 10.12.2

From package.json:

"jest": {
  "testEnvironment": "jsdom"
},
...
"babel-jest": "^18.0.0",
"jest": "^18.1.0",
@thymikee
Copy link
Collaborator

You should be able to mock console.warn and window.crypto for every test

@danieldiekmeier
Copy link
Author

If I mock console.warn, I lose every warning, not just that one warning that I don't want.

If I mock window.crypto, I have to match the part of the implementation that node-uuid uses, which seems very brittle to me. Any suggestions how to do this?

@thymikee
Copy link
Collaborator

for the this particular test suite or even test case you can do something like:

const warn = console.warn;
console.warn = jest.fn(); // mock console
// tests...
console.warn = warn // restore console

You should be able to mock node-uuid too:

jest.mock('node-uuid', () => {
  return {
    v4: jest.fn(() => 1)
  };
});

@danieldiekmeier
Copy link
Author

Oh, thanks, that did it! (For this case)

Should I close this, or could the feature request in general be considered for jest?

@thymikee
Copy link
Collaborator

If you're interested in creating something like this, feel free to send a PR.
But it won't be high on our priorities list I guess.
@cpojer what do you think?

@thymikee
Copy link
Collaborator

But it won't be high on our priorities list I guess.

I mean implementing such feature by us, not your PR – pull requests are always welcome, but it's often good to discuss the topic before diving in.

@mathieumg
Copy link
Contributor

I would also welcome a feature like this. With the jsdom versus node envs, is it just the bootstrapping of the former that takes longer or is it a bit slower generally speaking?

As a side question, how would one go about testing code that's meant to run both in the browser and in node, but that behaves slightly differently depending on where it runs?

@cpojer
Copy link
Member

cpojer commented Jan 23, 2017

We could add:

/**
 * @testEnvironment jsdom
 */

and toggle based on the specified value. I'd be supportive of such a change to Jest.

@SimenB
Copy link
Member

SimenB commented Feb 10, 2017

I'd like to look into this, but I'm unsure where to start.

It looks like the environment is bootstrapped before tests are ready (which is fine for the default even if this is implemented, I suppose) here: https://github.com/facebook/jest/blob/7ca7dac05797a6ba2beac4e423504be6ea858c44/packages/jest-runtime/src/cli/index.js#L79-L90

But where would I hook in to check for a @testEnvironment and then potentially create a new env and run that test on there?
A small push in the right direction, and hopefully I can implement this. 😄

@cpojer
Copy link
Member

cpojer commented Feb 10, 2017

@SimenB it's right here: https://github.com/cpojer/jest/blob/master/packages/jest-cli/src/runTest.js#L32 you have the path to the test file and this is where the env is created.

@SimenB
Copy link
Member

SimenB commented Feb 10, 2017

PR opened #2859

As a side question, how would one go about testing code that's meant to run both in the browser and in node, but that behaves slightly differently depending on where it runs?

I suppose we could add support for a comma based pragma, and then just run the same file twice? If there's interest in it, I can look into it after #2859 is done. 😄

SimenB added a commit to SimenB/jest that referenced this issue Mar 2, 2017
SimenB added a commit to SimenB/jest that referenced this issue Mar 2, 2017
SimenB added a commit to SimenB/jest that referenced this issue Mar 2, 2017
SimenB added a commit to SimenB/jest that referenced this issue Mar 2, 2017
SimenB added a commit to SimenB/jest that referenced this issue Mar 2, 2017
SimenB added a commit to SimenB/jest that referenced this issue Mar 3, 2017
SimenB added a commit to SimenB/jest that referenced this issue Mar 3, 2017
cpojer pushed a commit that referenced this issue Mar 3, 2017
* Extract docblock into its own module

* Allow setting a test environment per file

Fixes #2587
skovhus pushed a commit to skovhus/jest that referenced this issue Apr 29, 2017
* Extract docblock into its own module

* Allow setting a test environment per file

Fixes jestjs#2587
tushardhole pushed a commit to tushardhole/jest that referenced this issue Aug 21, 2017
* Extract docblock into its own module

* Allow setting a test environment per file

Fixes jestjs#2587
@ljharb
Copy link
Contributor

ljharb commented Apr 30, 2018

@SimenB have you had a chance to look into #2587 (comment) ? We'd like to always run our tests with both jsdom and node testEnvironments, since we server-render everything - is there an easy way to do that in the same jest run?

@cpojer
Copy link
Member

cpojer commented Apr 30, 2018

You should be able to use Jest’s multi project runner to duplicate your config and change the test environment. That would run all tests twice in a single run.

@ljharb
Copy link
Contributor

ljharb commented May 1, 2018

Thanks! Is there documentation on that you could link to?

@cpojer
Copy link
Member

cpojer commented May 1, 2018

See https://facebook.github.io/jest/docs/en/configuration.html#projects-array-string-projectconfig

@ljharb
Copy link
Contributor

ljharb commented May 1, 2018

@cpojer thanks - all the documentation I found talks about how to use "projects", but not how, in a JSON config, to share configuration values across projects. Specifically, I tried to put things top-level, and only put per-project overrides in "projects", but that didn't work - it seemed to ignore all the top-level keys when "projects" was present, so I had to manually duplicate them.

@cpojer
Copy link
Member

cpojer commented May 1, 2018

Jest also supports JS configs nowadays, so I probably recommend using a top level JSON config that includes two JS configs that are proxies to the config object that's in a third file and only toggle the env. It's a bit complex but in the end it's a pretty powerful setup. For fewer files you can also only have two files: one that exports the default setup and one that exports that with the env overwritten.

@ljharb
Copy link
Contributor

ljharb commented May 1, 2018

If that’s the only way, I’d prefer to duplicate it; i don’t like having logic in configs :-/

@ljharb
Copy link
Contributor

ljharb commented May 1, 2018

Is there any way that top-level values could get inherited down into projects when both are specified?

@SimenB
Copy link
Member

SimenB commented May 6, 2018

Can you open up a separate issue for that? It kinda goes back to the discussion here: #5176 (comment)

The difference between GlobalConfig and ProjectConfig is not easy to understand, and things like the inheritance you mention is not really possible (and it's non-obvious).

To answer your question - I have not looked into it. jest-docblock supports multiple identical pragmas now, so in theory it should be possible. But I think multiple projects makes more sense for that use case

@thephilwells
Copy link

I think I've lost the thread. Is this work complete? Is the way to change the test environment on a per file basis documented somewhere?

@SimenB
Copy link
Member

SimenB commented Jan 15, 2020

https://jestjs.io/docs/en/configuration#testenvironment-string

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants