最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Does Jest import every test file individually, or does it mount all the references one time before executing? - Sta

programmeradmin3浏览0评论

I have several unit tests, and each module imports a lot of data resources from a JSON file via a method. This IIFE method is imported by every test module, and I'm trying to figure out why my tests are so slow. The JSON data is massive, so I'm guessing that the reason this is the case, is because every test imports the huge data as it is ran. If this is the case, I'll have to modify the method, to return only specific data sets.

So my question is, is the data imported every single time each test module runs, or only once when I execute npm run test?

A basic example of the structure I have: Codesandbox. Say test1.js requires only dataset_1 key from the data json, and the other two test files need dataset_2. Would it be more performant to write a method that returns the required data props to the test file that it is invoked in, or it doesn't matter? Trying my best to phrase this question correctly, please let me know what else I can clarify.

I have several unit tests, and each module imports a lot of data resources from a JSON file via a method. This IIFE method is imported by every test module, and I'm trying to figure out why my tests are so slow. The JSON data is massive, so I'm guessing that the reason this is the case, is because every test imports the huge data as it is ran. If this is the case, I'll have to modify the method, to return only specific data sets.

So my question is, is the data imported every single time each test module runs, or only once when I execute npm run test?

A basic example of the structure I have: Codesandbox. Say test1.js requires only dataset_1 key from the data json, and the other two test files need dataset_2. Would it be more performant to write a method that returns the required data props to the test file that it is invoked in, or it doesn't matter? Trying my best to phrase this question correctly, please let me know what else I can clarify.

Share Improve this question edited Jun 18, 2020 at 10:58 Mike K asked Feb 20, 2020 at 14:39 Mike KMike K 6,54117 gold badges75 silver badges145 bronze badges 2
  • 1 Modules should be imported only once, but it depends on your test package and structure... about data loading it's impossible to answer without the code. – Daniele Ricci Commented Jun 18, 2020 at 8:44
  • Could you share what test runner you are using? – Drag13 Commented Jun 18, 2020 at 9:17
Add a ment  | 

3 Answers 3

Reset to default 7 +100

Yup, I think you need to update your tests. This is what the docs say, in the resetModules configuration switch section:

... each test file gets its own independent module registry.

This tallies with the behaviour I've observed. For each test file the whole runtime is rebuilt, meaning all modules are imported from scratch. That makes sense, because it means that mon test bugs related to mutable global state not being cleaned up between tests are eradicated.

Also, it's worth noting jest can (if not always does) use subprocesses to run each test, so that it can be parallelized more easily, which is another reason why it makes sense to do a pletely fresh setup for each test file. You can switch this off by using --runInBand, but that doesn't change the behaviour, see the example below.

On a default install, you can see the problem by simply putting a console.log() statement in an import file, and then having two tests import it, something like:

mylib.js

console.log('Hello from mylib.js!');

jests/test1.js

const mylib = require('../mylib');
describe('test1', () => {
  it('should be equal', () => {
    expect(1).toEqual(1);
  });
});

jests/test2.js

const mylib = require('../mylib');
describe('test2', () => {
  it('should be equal', () => {
    expect(2).toEqual(2);
  });
});

I get output along the lines of:

 3.2: npm run jest -- --runInBand jests/test*

> [email protected] jest /path/to/cwd
> jest "jests/test1.jest.js" "jests/test2.jest.js"

(node:60746) ExperimentalWarning: The fs.promises API is experimental
 PASS  jests/test1.jest.js
  ● Console

    console.log
      Hello from mylib.js!

      at Object.<anonymous> (mylib.js:1:9)

 PASS  jests/test2.jest.js
  ● Console

    console.log
      Hello from mylib.js!

      at Object.<anonymous> (mylib.js:1:9)


Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.075 s
Ran all test suites matching /jests\/test1.jest.js|jests\/test2.jest.js/i.

I don't know how it imports data and how it works. But whenever you write test cases your data should not be huge. Actually we only need to test the functionality or role of any ponent, is it working according to our flow design or not. That's it. So your data for test cases should be small in amount.

From node.js side, no reload problem at all. JSON files are read and parsed only once, then cached and the cached version is returned for each require call. Pay attention, what is cached it the parsed JavaScript Object, so if cached version is changed, next require call will returns the changed version.

From jest side, there could be a reload problem; reading at the doc, it seems that without the --runInBand option more processes are launched: you could try it to check if it solves your problem.

As last chance you can trust require cache and test if by yourself: only for this test purpose you can change the cached version in test1.js and check if cached version is still changed in test2.js, if it is still changed: no, the source of your problem is somewhere else, if changes applied in test1.js are lost: yes, you are reloading (and reparsing) the entire json file.

Hope this helps.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论