Jest fails with 'Cannot find module' when restricted to a single suite but succeeds when testing multiple suites - jestjs

I have a typescript project containing multiple Jest test suites. If I run all of the suites together using
npm test
then all the tests are executed.
I can filter the tests that run by using a command like
npm test -- LayoutView
Jest then only executes the tests from modules whose names contain the text LayoutView. We get a response
> jest --config=./configs/jest.config.ts "LayoutView"
PASS tests/actions/LayoutViewHide.test.ts
PASS tests/actions/LayoutViewCopy.test.ts
PASS tests/actions/LayoutViewMove.test.ts
Test Suites: 3 passed, 3 total
Tests: 47 passed, 47 total
Snapshots: 0 total
Time: 6.724 s
Ran all test suites matching /LayoutView/i
However if I further restrict the pattern so that it only matches a single test file like this then it fails.
npm test -- LayoutViewH
giving an error like this:
> jest --config=./configs/jest.config.ts "LayoutViewH"
FAIL tests/actions/LayoutViewHide.test.ts
● Test suite failed to run
Cannot find module 'source-map-support' from 'node_modules/#cspotcode/source-map-support/source-map-support.js'
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:306:11)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 0.095 s, estimated 5 s
Ran all test suites matching /LayoutViewH/i.
It seems that whenever I try to test from a single suite it fails, whenever the test covers multiple files then it succeeds. This is preventing me from debugging a failed test, since VSCode is trying to run a single test, and fails with the same error message I can see in the command line.
Looking at Jest - Cannot find module 'source-map' from 'source-map-support.js' I checked the moduleDirectories property in my jest.config.ts file. It reads
moduleDirectories: ['node_modules', 'src'],
I need to have 'src' here since I am using absolute paths within my code, relative to a directory called src below my root directory.
Besides if I have the includes miss-configured, why does it work when testing several suites at once? Any idea what might be causing this?
I am running:
node --version: v16.15.1
Jest version: 26.6.3
My jest.configure.ts file reads
module.exports = {
rootDir: '../',
roots: [ '<rootDir>/tests/' ],
transform: {
'.+\\.(css|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
'^.+\\.tsx?$': 'ts-jest',
'^.+\\.js$': '<rootDir>/node_modules/babel-jest'
},
testRegex: '\\.test\\.(ts|tsx|js)$',
moduleFileExtensions: ['ts', 'tsx', 'js'],
moduleDirectories: ['node_modules', 'src'],
testEnvironment: 'node',
};
The relevant part of the "package.json" file contains
{
"scripts": {
"test": "jest --config=./configs/jest.config.ts"
}
}

Related

Difference in running one and many files in jest

I'm using jest (^28.1.3) for running unit and e2e tests on backend (Apollo Server, TypeORM and PostgreSQL). There aren't problems to run unit tests (one file, two or all), but I have a problem with e2e testing.
On local machine
If I run one file with e2e tests (e.g. regression.e2e-spec.ts), I'll get an error.
If I run two files (e.g. regression.e2e-spec.ts + someUnit.test.ts, or regression.e2e-spec.ts + otherE2ETest.e2e-spec.ts), I won't get any error, testing will finished successful.
On GitHub Actions
I get same error in any cases (run one, two or all files)
May jest execute tests in main process/thread when it finds only one file? And split execution on several process when find several files?
The problem might be in an isolation, with one file environment isn't clean.
Files are filtered in jest.config.js, write file name in testMatch.
/** #type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
roots: ['<rootDir>/src'],
testEnvironment: 'node',
testMatch: ['**/src/**/*.(test|e2e-spec).ts'], // keep in sync with src/__test__/setup/E2ERegExp.ts
globalSetup: './src/__test__/setup/globalSetup.ts',
globalTeardown: './src/__test__/setup/globalTeardown.js',
setupFilesAfterEnv: ['./src/__test__/setup/setup.ts'],
transform: {
'^.+\\.ts': 'ts-jest',
},
};
In globalSetup and globalTeardown I setup and drop databases. In setup.ts run server and connect to db.
Tests are executed in parallel.
"docker:test": "RUN_DB=true NODE_OPTIONS=--max-old-space-size=4096 jest --colors --maxWorkers=50%",

Testing a node app with `npm run test --runInBand --detectOpenHandles --forceExit` doesn't detect open handles

The jest tests for my node app keep returning a warning about not returning gracefully:
A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --runInBand --detectOpenHandles to find leaks.
The question Jest error on upgrading to latest version - a worker process has failed to exit gracefully mentioned the documentation suggests --forceExit.
I'm using VSCode on WSL1, and here is how I have started running my tests:
user:~/ponder$ npm run test --runInBand --detectOpenHandles --forceExit
> ponder#1.0.0 test
> jest
PASS ./entries.spec.js
PASS ./constraints.spec.js
PASS resources/csvToJson.spec.js
PASS resources/resources.spec.js
A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --runInBand --detectOpenHandles to find leaks.
Test Suites: 4 passed, 4 total
Tests: 10 passed, 10 total
Snapshots: 0 total
Time: 34.906 s
Ran all test suites.
But as you can see, I am still getting the warning?
My jest config is:
module.exports = {
testEnvironment: 'node',
maxWorkers: 4,
testTimeout: 20000,
};
And webpack is:
const webpack = require('webpack'); // to access built-in plugins
module.exports = {
mode: 'development',
plugins: [
new webpack.IgnorePlugin(/(fs|child_process)/),
],
};
and in my package.json file, the scripts object just aliases test to jest with not extra options.
Before I start investigating my tests, is there another CLI option or configuration to help me find the leak?

Jest is failed to running with Mock files with Error Message Your test suite must contain at least one test

I have webpack and jest,I have my jest option setting as below:
"moduleNameMapper": {
"^.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__tests__/__mocks__/fileMock.js",
"^.+\\.(css|less)$": "<rootDir>/__tests__/__mocks__/styleMock.js"
}
}
styleMock.js content:
export default '';
fileMock.js content:
export default 'test-file-stub';
Jest Fail to Run. with below error:
FAIL __tests__/__mocks__/fileMock.js
● Test suite failed to run
Your test suite must contain at least one test.
FAIL __tests__/__mocks__/styleMock.js
● Test suite failed to run
Your test suite must contain at least one test.
It's just that Jest should not try to execute those files as tests. You should change the testMatch in jest.config.js to only check for .spec.js files or .test.js files :
testMatch: [
"**/__tests__/**/*.[tj]s?(x)",
"**/?(*.)+(spec|test).[tj]s?(x)"
],

Jest regex to match certain test files

I have integration tests under dir src/test/integration. All files are named like so: foo.integration.js.
Running Jest:
jest ".*\\.integration\\.js"
produces this error:
No tests found, exiting with code 1
Run with `--passWithNoTests` to exit with code 0
In /Users/dangruszczyk/workspace/cef/lambda-workflow
7 files checked.
testMatch: **/__tests__/**/*.[jt]s?(x), **/?(*.)+(spec|test).[tj]s?(x) - 1 match
testPathIgnorePatterns: /node_modules/ - 7 matches
testRegex: - 0 matches
Pattern: .*\.integration\.js - 0 matches
Surely this regex should match src/test/integration/foo.integration.js (https://regex101.com/r/T3WJwd/1/). Any clue why it does not?
The problem is that Jest is still applying the testMatch, i.e. you're filtering within the files it has already determined to be test files, and src/test/integration/foo.integration.js matches neither **/__tests__/**/*.[jt]s?(x) nor **/?(*.)+(spec|test).[tj]s?(x)*.
To run those files, you're probably best off setting the testMatch instead:
jest --testMatch='**/*.integration.js'
This doesn't seem to be a documented part of the CLI, but works fine (for now!) in practice.
* Interestingly, neither does path/to/my-test.js, the example shown in the docs...
I was doing the same thing, but in the end it felt more natural to restructure.
By using .test.js you can easily run all tests or selectively filter sub-types.
example.integration.test.js
example.unit.test.js
"scripts": {
"test-all": "jest",
"unit-test": "jest \"--testPathPattern='.+\\.unit\\.test\\.js$'\"",
"integration-test": "jest \"--testPathPattern='.+\\.integration\\.test\\.js$'\""
},
As others have said, jest expects test files to end .test.js or .spec.js.

How to prevent Jest from printing all skipped tests?

I'm trying to run just one Jest test, and am I using the following command:
jest --config=jest.config.js --runInBand --bail --forceExit "services_rest_Api" "-t" "should list all tag notes"
With the following config:
module.exports = {
testMatch: [
'**/tests/**/*.js',
],
testPathIgnorePatterns: [
'/node_modules/',
'tests/support/',
'test-utils.js',
'file_api_driver.js',
],
testEnvironment: 'node',
setupFilesAfterEnv: ['./jest.setup.js'],
};
Whenever I run this, it displays the filtered test on top, but also all the skipped one below:
PASS tests/services_rest_Api.js
services_rest_Api
✓ should list all tag notes (852 ms)
○ skipped should ping
○ skipped should handle Not Found errors
○ skipped should get folders
// ... And many more of these
Which means I need to scroll up by a lot to actually see the results for the test I was running. So I'm wondering, is there any way to prevent Jest from printing all these skipped tests? I didn't include the verbose anywhere so I thought it shouldn't print this but it still does. Any idea?
To disable verbosity you could either set it:
cli
jest --verbose=false
or in:
jest.config.json/package.json
{
"verbose": false
}
and even the documentations says by default it's false by default
it's enabled when you run tests for a single file

Resources