Config changes not being picked up when running test coverage with Jest - jestjs

I am looking for a way to exclude entire folders/files from my testing coverage with Jest. I have gone through the official Jest documentations several times, but have been unable to get it to work. I've come to the conclusion that maybe my jest.config.js isn't being picked up, because no matter what changes I make to the collectCoverageFrom or testPathIgnorePatterns fields, the test coverage return does not change, and it includes everything, even the things I am trying to exclude. Here is my test coverage script in the package.json:
"test-coverage": "npm test --config='jest.config.js' --coverage "
and here is my jest.config.js:
module.exports = {
roots: ['<rootDir>', '<rootDir>/src', '<rootDir>/tests'],
testEnvironment: 'jsdom',
testPathIgnorePatterns: ['/node_modules/'],
collectCoverage: true,
collectCoverageFrom: ['./src/**/*.{js, jsx}', '!**/node_modules/**', '!**/vendor/**'],
coverageDirectory: './coverage',
}
For the files I am excluding, I am just using this format: !src/folder/file.js as per the official jest
documentation.
Any help appreciated.
Things I did to troubleshoot:
I added the path to the Jest config into the test-coverage command, but that was unsuccessful.
I have set the collectCoverage field above to true, no success.
I added the jest config to the actual package.json, but even that
did not change anything. Here is the format for it inside my
package.json:
"jest": {
"roots": ["<rootDir>", "<rootDir>/src","<rootDir>/tests"],
"testEnvironment": "jsdom",
"testPathIgnorePatterns": ["/node_modules/"],
"collectCoverage": true,
"collectCoverageFrom": ["./src/**/*.{js,jsx}","!**/node_modules/**","!**/vendor/**"],
"coverageDirectory": "./coverage"
}

Related

Jest fails when script imports external library

I just started testing with Jest for the first time. This is a very simple Typescript utils library. I basically followed the installation guide, and my first two tests passed. Yay. The next function I tested imported a few functions from lodash-es, and failed (error below).
This is how I added jest:
pnpm add -D jest ts-jest #types/jest
pnpx ts-jest config:init
My jest.config.js file, as generated by pnpx ts-jest config:init, except that I had to change the second line to export default, because my package.json specifies this to be a module.
/** #type {import('ts-jest').JestConfigWithTsJest} */
export default {
preset: 'ts-jest',
testEnvironment: 'node',
transformIgnorePatterns: [
"node_modules/(?!(lodash-es)/)"
],
moduleNameMapper: {
'lodash-es': '../node_modules/lodash-es/lodash.js',
},
}
I've tried adding transformIgnorePatterns and moduleNameMapper, based on others with similar issues. But no luck.
The error message:
D:\Dev\NodeJs\vexna\packages\util>pnpm test
> #vexna/util#1.0.0 test D:\Dev\NodeJs\vexna\packages\util
> jest
PASS test/reverseString.test.ts
PASS test/hash.test.ts
FAIL test/uid.test.ts
● Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
D:\Dev\NodeJs\vexna\node_modules\.pnpm\lodash-es#4.17.21\node_modules\lodash-es\lodash.js:10
export { default as add } from './add.js';
^^^^^^
SyntaxError: Unexpected token 'export'
> 1 | import { now, random, padStart, padEnd } from "lodash-es"
| ^
2 | import { reverseString } from "./reverseString"
3 |
4 |
at Runtime.createScriptFromCode (../../node_modules/.pnpm/jest-runtime#29.4.1/node_modules/jest-runtime/build/index.js:1598:14)
at Object.<anonymous> (src/uid.ts:1:1)
at Object.<anonymous> (test/uid.test.ts:1:1)
Test Suites: 1 failed, 2 passed, 3 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 3.494 s
Ran all test suites.
 ELIFECYCLE  Test failed. See above for more details.
A few things, this project exists in pnpm monorepo, in case it matters.
This is the package.json:
{
"name": "#vexna/util",
"version": "1.0.0",
"description": "Generic utilities, uses lodash",
"private": true,
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"sideEffects": false,
"scripts": {
"build": "rimraf dist && tsc && rollup -c rollup.config.js",
"test": "jest",
"pretest": "npm run build"
},
"devDependencies": {
"#rollup/plugin-typescript": "^11.0.0",
"#types/jest": "^29.4.0",
"#types/lodash-es": "^4.17.6",
"jest": "^29.4.1",
"lodash-es": "^4.17.21",
"rimraf": "^4.1.2",
"rollup": "^3.12.1",
"ts-jest": "^29.0.5",
"typescript": "^4.9.5"
},
"files": [
"dist"
],
"peerDependencies": {
"lodash": "^4.17.21"
}
}
I suspect that perhaps Jest goes off into the boonies because I have externalized lodash?
Or perhaps I should add Babel? But could just as well be something else completely.
Some help is much appreciated!
Use Vitest.
Jest is quite painful to install correctly, whereas Vitest works out of the box without any config. This is my personal experience. It took me days to get Jest to sort-of work. I had Vitest working immediately after installation.
I don't want to hate on Jest, I actually think it's a wonderful and intuitive testing tool. But ultimately Vitest "Just Works" (tm), and you can use the same simple Jest style API we all have come to love.
Steps:
pnpm remove jest ts-jest #types/jest
pnpm add -D vite vitest
Delete jest.config.js, and create vite.config.ts:
/// <reference types="vitest" />
import { defineConfig } from 'vite'
export default defineConfig({
test: {
/* for example, use global to avoid globals imports (describe, test, expect): */
// globals: true,
},
})
Add to your tests:
import { assert, expect, test } from 'vitest'
Update your package.json:
"test": "vitest",

Jest - SyntaxError: Cannot use import statement outside a module with #nestjs/axios

I'm just trying to run some integration tests on a nestjs app, but I'm getting the following error:
SyntaxError: Cannot use import statement outside a module
I spent a lot of time on this problem that should be easy to fix but I can't deal with it.
This problem occurs with #nestjs/axios lib which uses ESM instead of CommonJs. After doing some research, I saw that theoretically I should run the tests with this command:
yarn node --experimental-vm-modules $(yarn bin jest)
But nothing i do works
I also don't understand why this file is being matched since it is in node_modules
Can someone help me?
My Jest config:
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "",
"preset": "ts-jest",
"testRegex": ".spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "./coverage",
"testEnvironment": "node",
"globalSetup": "<rootDir>/tests/jest.setup.ts",
"globalTeardown": "<rootDir>/tests/jest.teardown.ts"
}
My versions:
"#nestjs/axios": "^1.0.1",
"#types/jest": "^24.0.18",
"jest": "^26.0.0",
"ts-jest": "^26.5.5",
"typescript": "^4.2.3"
I've already tried putting node_modules (which is already jest's default behavior) in the transformIgnorePatterns setting, but it's not working.
The lib I'm having this error is an internal lib (node_modules/#bank/auth/node_modules/#nestjs/axios/node_modules/axios/index.js:1), could it be the reason for the problem?
This has to do with jest and ts-jest seeing the library as an ESM module due to how the package.json is set up. You should be able to add this to your jest config and have no issues.
moduleNameMapper: {
'^axios$': require.resolve('axios'),
},
This should force jest to resolve the library correctly from node_modules

E2e test report generate in jest and nest.js node

Have used jest --config /path/jest-e2.json --coverage
But it's not generating any files only blank index file. Though test are running. I want to have a report of e2e test.
e2e setting
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"coverageDirectory": "../coverage/e2e",
"coverageReporters" : ["json", "lcov", "text", "clover"],
"coveragePathIgnorePatterns": [
".module.ts$",
".spec.ts$"
]
}
I had a similar issue generating coverage for my Ogma integration tests, it seems Jest won't collect coverage from outside the rootDir. To fix this, I set my rootDir as my project root (made the jest-integration.config.js on the same level as package.json) and told it to only collect coverage from src/**/*.ts while ignoring *.spec.ts files. Fixed the issue for me (it's a monorepo so the collectCoverageFrom structure is slightly different, but the idea is the same)

Why would Jest test randomly fail if not in watch mode?

I'm having a weird problem. If I run
jest --watch
via npm, everything works as expected.
If I turn on coverage, then I get random errors, mostly like this
ENOENT: no such file or directory, lstat
More details
The command that is reliable is defined in package.json as:
"test": "jest --watch --config jest-watch.json",
The command that is not reliable is
"test-all": "jest"
We use a jest.config.js file:
module.exports = {
verbose: false,
testURL: 'http://localhost/',
coverageReporters: ['json', 'lcov', 'html'],
collectCoverageFrom: [
'<rootDir>/src/**/*.{js,jsx}',
'!**/node_modules/**',
'!**/vendor/**',
'!**/coverage/**',
'!<rootDir>/lambda.js',
'!<rootDir>/server.js'
],
collectCoverage: true,
coverageThreshold: {
global: {
statements: 40,
branches: 17,
functions: 18,
lines: 41
}
},
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
testPathIgnorePatterns: ['<rootDir>/lambda.js', '<rootDir>/server.js']
};
and the `jest-watch.config' file is:
{
"collectCoverage": false,
"setupFilesAfterEnv": ["<rootDir>/setupTests.js"]
}
This is happening in every project I use jest, both node and react apps. However, I have about 10+ teammates, some on Windows and some on Macs and nobody else is having this problem. I believe I'm the only one using WSL (Windows Subsystem for Linux).
I'm running Windows 10 1803. I'm using Ubuntu as my Linux distro.
Any ideas on what could be causing this?
I don't test it, but your configuration looks fine, I've some question:
1- Do you use jest Global or local in your project?
2- What happened when you run inside the project folder "npm run test"?
3- have you tried to run "jest --watch" inside the project folder?
Note: Because you're using WSL you should check your bash configuration, your shell, and your $PATH environment variable.

How to collect code coverage for spawned sub-processes using Jest?

I am writing integration tests for a CLI. All the unit tests are written using Jest as out-of-the-box it produces code coverage without any configuration, but unfortunately it does not instrument sub-processes, for example executed via Node's spawn and fork commands.
I have tried to introduce nyc into the mix as suggested in this comment on a GitHub issue however it has not worked for me.
I have played with various configurations (based on the initial aforementioned suggestion and also ideas from these issues: 1, 2), however either I get no coverage statistics at all or only coverage for my unit tests, not the integration tests that spawn sub-processes.
The relevant parts of my package.json which configures nyc and Jest:
"scripts": {
"test": "cross-env NODE_ENV=test nyc --clean jest --coverage",
},
"jest": {
"verbose": true,
"testURL": "http://localhost/",
"globalSetup": "./jest.setup.js",
"transform": {
"^.+\\.js$": "babel-jest"
},
"collectCoverage": false
},
"nyc": {
"include": [
"packages/*/src/**/*.js"
],
"reporter": [
"html"
]
},
I am using execa to run the sub-processes and do so as follows:
await execa("nyc --reporter none node", args);

Resources