Jest coverage reporting on all committed files in create-react-app - jestjs

Having difficulty with generating Jest coverage reports for all committed files in my create-react-app.
Initially, code coverage was generating as expected, however something has changed in my environment, and now only files changed since the last commit are showing coverage.
I see there are many other posts about this issue, however I am unable to resolve it myself.
package.json:
{...
"devDependencies": {
"#testing-library/jest-dom": "^5.11.9",
"#testing-library/react": "^11.2.5",
"#testing-library/user-event": "^12.6.3",
"react-test-renderer": "^17.0.1"
},
"jest": {
"testMatch": [ "**/tests/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)" ],
"coverageReporters": ["json","html","lcov", "text"]
}
...}
Project structure:
|
+--node_modules
+--src
|
+ __tests__
+ App.js
- package.json
Running command npm test -- --coverage produces the following output:
No tests found related to files changed since last commit.
Press `a` to run all tests, or run Jest with `--watchAll`.
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
Watch Usage
› Press a to run all tests.
› Press f to run only failed tests.
› Press q to quit watch mode.
› Press p to filter by a filename regex pattern.
› Press t to filter by a test name regex pattern.
› Press Enter to trigger a test run.

You are in watch mode, which has a known issue when running coverage on a subset of files. Try using --watchAll so that all tests run and coverage can be generated.
npm test -- --coverage --watchAll
I like to make a special npm run-script in my package.json called coverage for this purpose.

You need to run this script react-scripts test --coverage with a included in order to run all tests.
Before:
react-scripts test --coverage
After:
react-scripts test --coverage a

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",

Working with quotes when using NPM package variables

I have a jest command that looks like this:
npx jest index.test --testMatch "**/test/*.cjs"
This looks in the ./test directory for test files matching the extension .cjs.
The above command works as expected.
However, I'm having an issue when trying to alias this command via NPM using package.json variables.
Here's the file:
// package.json
...
"config": {
"testmatch": "--testMatch \"**/test/*.cjs\""
},
"scripts": {
"test1": "npx jest index.test $npm_package_config_testmatch",
"test2": "npx jest index.test --testMatch \"**/test/*.cjs\""
}
...
For npm run test1 I get the following result:
No tests found, exiting with code 1
...
For npm run test2 I get the desired result, i.e. Jest runs all the tests and outputs the result.
The two are essentially the same commands, but test1 doesn't work.
When I used the --debug flag for Jest (for both commands) I noticed that Jest appears to be receiving two different values for testMatch:
// npm run test1
...
"testMatch": [
"\"**/test/*.cjs\""
],
...
// npm run test2
...
"testMatch": [
"**/test/*.cjs"
],
...
This would explain why the npm run test1 fails: the pattern is malformed.
Is there some way to deal with the quote character " when using them inside NPM package variables?

Is there a way to run yarn test (jest) and directly update interactively?

Here's the current situation:
Whenever we push the code to our build servers, the tests are run on those servers.
When tests fail I have a list of failed tests I need to fix and it would be a timesaver if instead of running yarn test then proceed through the options by choosing "run all tests" and "i update interactively" to just go to that interactive update directly.
I've looked through some of the jest documentation, but couldn't find a clear answer whether it's possible to start it directly. For example by doing something like yarn test -update -interactive (made up parameters as example).
Why don't you use the watch mode
yarn run test --watch
For integration with commit and push you need to create git hooks, you may have a look at husky
{
"husky": {
"hooks": {
"pre-commit": "yarn test -u -t="your test title goes here" --watch",
"pre-push": "yarn test",
"...": "..."
}
}
}

Run a single test file using Node js Mocha

All my tests are under test folder and when I give npm test all the tests are getting executed. Now I am trying to run my test scripts by file or by it's describe. I have the following in my package.json
"scripts": {
"test": "set NODE_ENV=test&& nyc --reporter=html --reporter=text mocha 'test/**/*.js' --exit --timeout 7000"}
When I give npm test --grep 'filename / describe / it' it is not picking up the given input instead I'm getting the following warning Warning: Cannot find any files matching pattern "given filename / describe /it" even though given input matches.
My filename pattern is filename.test.js and the folder structure is like test\***\filename.test.js
Can anyone guide me on what I'm missing on this.
You need to include the grep option within the npm command:
"scripts": {
"test": "set NODE_ENV=test&& nyc --reporter=html --reporter=text mocha 'test/**/*.js' --exit --timeout 7000 --grep"
}
Then call it with:
npm run test <name of test>

husky+lint-staged runs on unstaged files

I'm trying to add a pre-commit git hook that will run my linter only on touched (staged) files. My project is based on Create React App.
I added the following to my package.json:
"scripts": {
"lint": "eslint 'src/**/*.js'",
"lintfix": "eslint 'src/**/*.js' --fix"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*": ["npm run lintfix --", "git add"]
}
The reason I run it on "*" is because I'm expecting the script itself (lintfix) to enforce it's configuration (src/**/*.js).
The problem is that I'm getting plenty of eslint errors on my entire codebase and not only on staged files as I wished.
What's the configuration I need for running my eslint only on staged files?
From lint-staged readme.md :
{ "*": "your-cmd" }
This config will execute your-cmd with the list of currently staged
files passed as arguments.
So, considering you did git add file1.ext file2.ext, lint-staged will
run the following command:
your-cmd file1.ext file2.ext
So looking at your package.json, you are running the following :
eslint 'src/**/*.js' --fix file1.js file2.js file3.js fileX.js... ....
You need to replace npm run lintfix -- by eslint --fix to first test if it works (it should), then adapt your lintfix command without the generic src/**/*.js regex.

Resources