I have jest.config.js as below:
module.exports = {
"roots": [
"<rootDir>/src"
],
"testMatch": [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
"testResultsProcessor": "jest-sonar-reporter",
"collectCoverage": true,
"collectCoverageFrom": [
"**/*.{ts,js}",
"!**/node_modules/**"
],
"coverageDirectory": "dist",
"coverageReporters": ["lcov"]
}
A report file test-report.xml is generated in the project root directory. How can I make it to be saved in dist directory?
Also you can configure it in jest configuration in package.json file
"jest": {
"coverageDirectory": "<rootDir>/reports",
}
According to your configuration a report file test-report.xml is generated by jest-sonar-reporter. You can change jest-sonar-reporter output directory by adding the following section to package.json:
"jestSonar": {
"reportPath": "dist"
}
Reference: https://github.com/3dmind/jest-sonar-reporter
You can add --coverageDirectory in your script for test case.
react-scripts test --coverageDirectory='test-coverage' --coverage --watchAll=false
My comment appeared to help, so here it is as an answer:
If you're using jest-junit-reporter, then you can change the output directory of the generated test-report.xml file by setting the TEST_REPORT_PATH environment variable with the desired path.
You can change the path like this.
coverageReporters: ["json", ["lcov", {"projectRoot": "../../"}]]
Related
I have a nest app that is using monorepo mode. I would like to take advantage of the new repl feature that was released in nest 9.0+.
My directory structure looks as such:
apps/
--inventory-ops/src/app.module
--ticket-office/src/app.module
I have followed the instructions found in the docs creating a repl.ts, but when I run the repl commannd:
npm run start -- --entryFile repl
I get this error output:
Error: Cannot find module '/dist/apps/ticket-office/repl'
Looking at my dist folder, the only build target is main.js, which would explain it not being able to find the repl module. Do I need to update something in my webpack config to make sure repl.ts gets built as well? Any help would be appreciated.
I managed to solve this by adding a new project in nest-cli.json, for example:
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "#nestjs/schematics",
"sourceRoot": "apps/gateway/src",
"monorepo": true,
"root": "apps/gateway",
"compilerOptions": {
"webpack": true,
"tsConfigPath": "apps/gateway/tsconfig.app.json"
},
"projects": {
"gateway": {
"type": "application",
"root": "apps/gateway",
"entryFile": "main",
"sourceRoot": "apps/gateway/src",
"compilerOptions": {
"tsConfigPath": "apps/gateway/tsconfig.app.json"
}
},
"ticket-office": {
"type": "application",
"root": "apps/ticket-office",
"entryFile": "main",
"sourceRoot": "apps/ticket-office/src",
"compilerOptions": {
"tsConfigPath": "apps/ticket-office/tsconfig.app.json"
}
},
"ticket-office:repl": { // <<--- HERE
"type": "application",
"root": "apps/ticket-office",
"entryFile": "repl", // <<-- HERE
"sourceRoot": "apps/ticket-office/src",
"compilerOptions": {
"tsConfigPath": "apps/ticket-office/tsconfig.app.json"
}
},
}
}
Then you can run nest start ticket-office:repl
I hope this helps.
EDIT:
Adapted the answer to your question.
Try to run this:
nest start <your-app> --config nest-cli.json --debug --watch -- --entryFile repl
I faced the same issue and this worked for me.
I don't really know why NestJS take repl file into consideration for building only when explicitly the cli config is provided. It's probably a bug with the CLI.
Alternative
Also, you can add a custom parameter to your command and start the REPL mode conditionally:
script:
nest start <your-app> --watch repl
main.ts file:
async function bootstrap() {
if (process.argv[process.argv.length - 1] === 'repl') {
return repl(AppModule);
}
// Non REPL mode Nest app initialisation
...
}
bootstrap();
First of all, some facts:
Node.js requires that all local imports include the imported module's extension (e.g. import hello from './hello.js', not import hello from './hello').
TypeScript will compile imports with or without the .js extension, which means a missing .js extension is a runtime error.
TypeScript doesn't transform imports to add the .js extension or convert .ts to .js.
In my Node.js project, I want to make missing a missing .js extension be a build-time error using the import/extensions ESLint rule. However, when I enable this rule using the following configuration:
{
"root": true,
"env": {
"node": true
},
"parser": "#typescript-eslint/parser",
"plugins": [
"#typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:#typescript-eslint/eslint-recommended",
"plugin:#typescript-eslint/recommended"
],
"settings": {
"import/resolver": {
"typescript": {},
"node": {
"extensions": [".js"]
}
}
},
"rules": {
"import/extensions": ["error", "ignorePackages"]
}
}
running eslint gives me the following error:
/sandbox/src/index.ts
1:19 error Missing file extension "ts" for "./hello.js" import/extensions
Source files:
// index.ts
import hello from "./hello.js";
hello();
// hello.ts
export default function hello() {
console.log("Hello");
}
CodeSandbox link: https://codesandbox.io/s/elated-germain-13glp7
I fixed this with the following config:
{
"root": true,
"env": {
"node": true
},
"extends": [
"eslint:recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:#typescript-eslint/eslint-recommended",
"plugin:#typescript-eslint/recommended"
],
"rules": {
"import/extensions": ["error", "ignorePackages"],
"import/no-unresolved": "off"
}
}
The main thing is to disable the "import/no-unresolved" rule and remove "settings"."import/resolver"."node". ("import/no-unresolved" is redundant as unresolved imports are resolved at the compilation stage.) Other items removed here were already being added as a result of extending the #typescript-eslint plugins.
I found an eslint plugin that can fix missing .js extensions for imports in .ts files, instead of just showing an error:
https://github.com/AlexSergey/eslint-plugin-file-extension-in-import-ts
https://www.npmjs.com/package/eslint-plugin-file-extension-in-import-ts
Install:
npm i -D eslint-plugin-file-extension-in-import-ts
Add to .eslintrc file:
{
"plugins": [
"file-extension-in-import-ts"
],
"rules": {
"file-extension-in-import-ts/file-extension-in-import-ts": "error"
}
}
NOTE: I ran into an issue similar to https://github.com/import-js/eslint-plugin-import/issues/1292 when using this package, and it will incorrectly try to add .js extensions on these paths when fixing automatically.
You could try ts-add-js-extension package to append .js extension to the transpiled JavaScript files. After you install you can do
ts-add-js-extension add --dir={your-transpiled-outdir}
I'm struggeling now for a couple of days to get my testsetup running. Rough outline: Vite, Svelte (with ts), Jest.
I'm using import.meta.env.SOMENAME for my environment vars although this works fine for development as soon as a component uses import.meta.env the test will fail with:
SyntaxError: Cannot use 'import.meta' outside a module
I've tried different transformers, babel-plugins and configs but never succeeded...
My jest config:
"jest": {
"globals": {
"ts-jest": {
"isolatedModules": true
}
},
"verbose": true,
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": true
}
],
"^.+\\.ts$": "ts-jest",
"^.+\\.js$": "babel-jest"
},
"setupFilesAfterEnv": ["<rootDir>/setupTests.ts"],
"moduleFileExtensions": ["js", "ts", "svelte"]
}
babel.config.js
module.exports = {
presets: [
[
"#babel/preset-env",
{
targets: {
node: "current"
}
}
]
]
};
svelte.config.cjs
const sveltePreprocess = require('svelte-preprocess')
module.exports = {
emitCss: true,
preprocess: sveltePreprocess()
};
Among other things I tried to use #babel/plugin-syntax-import-meta but ended up with the same error. Also vite-jest looked very promising but again I couldn't make it work.
I appreciate every hint I can get. If I can provide any additional info please let me know. Also my knowledge of vite and babel is very limited so REALLY appreciate any help IU can get on this topic.
Update (Solution)
So If you use babel you could use babel-preset-vite. The approach with esbuild-jest from Apu is also good solution that many people use. Unfortunately those things didn't work for me so I decided to use a workaround with vite's define.
This workaround consists of two steps.
replace import.meta.env with process.env (if this is a deal breaker for you then I hope you have luck with the solutions above) You only have to replace the instances in files you want to test with jest.
Update Vite config with define. This step is necessary or your build will break (dev will still work)
vite.config.js
const dotEnvConfig = dotenv.config();
export default defineConfig({
define: {
"process.env.NODE_ENV": `"${process.env.NODE_ENV}"`,
"process.env.VITE_APP_SOMENAME": `"${process.env.VITE_APP_SOMENAME}"`
},
...
)};
I know this is just a workaround but maybe this helps someone. Thanks & Good Luck.
A more recent alternative to Jest that understands import.meta.env is Vitest.
It should require almost no additional configuration to get started and it's highly compatible with Jest so it requires few changes to the actual tests.
The advantages of Vitest over Jest for this use case are:
It's designed specifically for Vite and will process tests on demand
It will reuse your existing Vite configuration:
Any define variables will be replaced as expected
Extensions that Vite adds to import.meta will be available as usual
I was having issues with svelte component testing as well using jest. babel is not good at resolving import.meta. I used esbuild-jest to transform both ts and js files. It solves the issue with the import.meta. Here is my jest.config.cjs.
npm i esbuild esbuild-jest -D
const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig');
const config = {
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": true
}
],
"^.+\\.(ts|tsx|js|jsx)$": ["esbuild-jest"]
},
"moduleFileExtensions": [
"js",
"ts",
"tsx",
"svelte"
],
"setupFilesAfterEnv": [
"#testing-library/jest-dom/extend-expect"
],
"collectCoverageFrom": [
"**/*.(t|j)s",
"**/*.svelte"
],
coverageProvider: 'v8',
"coverageDirectory": "./coverage",
"coveragePathIgnorePatterns": [
"/node_modules/",
"/.svelte-kit/"
],
"moduleNameMapper": pathsToModuleNameMapper(compilerOptions.paths, {prefix: '<rootDir>/'})
};
module.exports = config;
I'm using the following jest.unittest.json file (used via jest --config option):
{
"bail": false,
"verbose": true,
"transform": {
"^.+\\.(ts|tsx)$": "typescript-babel-jest"
},
"testPathIgnorePatterns": [
"<rootDir>/lib",
"<rootDir>/lib_es6",
"/node_modules/",
"fixtures.ts",
"/fixtures/"
],
"moduleFileExtensions": [
"js", "jsx", "ts", "tsx", "node"
],
"roots": [
"<rootDir>/src/__unittests__/Logger",
"<rootDir>/src/__unittests__/Renderer/renderer.test.ts"
],
"testRegex": "<rootDir>/src/__unittests__/.*\\.test.(ts|tsx|js|jsx)$"
}
Note the test files are src/unittests/Renderer/renderer.test.ts, and so on.
It used to work until jest v19, but after upgrading to v20, this config no longer works.
When I do jest --config jest.unittest.json --verbose, I get:
Pattern: "" - 0 matches
Is there anything wrong with my config?
Try to change testRegex to something like that:
"(/src/__unittests__/.*|\\.(test|spec))\\.(ts|tsx|js)$"
I'd say it's interesting, that you configure 2 roots and use only one path in your testRegex. Also in the documentation they catch the path and the file name without extension, which is not the way you do it. Catch the path and filename with the parenthesis. See the documentation there (I'd skip <rootDir> too as you probably want to use both roots): https://jestjs.io/docs/configuration#testregex-string--arraystring
I am wrtiting a project using TypeScript, Jest and the ts-jest NPM module.
When I run my test, I do get some amount of coverage, but the HTML report is not quite right:
Furthermore, some functions are being marked as untested even though they are certainly being called.
My package.json is set as follows:
{
"jest": {
"transform": {
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"testResultsProcessor": "<rootDir>/node_modules/ts-jest/coverageprocessor.js",
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.{ts,tsx}"
],
"coverageReporters": [
"html",
"json"
]
}
}
Is something wrong with my configuration?
UPDATE
Starting from jest#20 you can pass mapCoverage option and use coverage/lcov-report/index.html file.
OLD
I also have been struggling with this problem, but then I notice that line.
Long story short - coverage reports goes to coverage/remapped/html/index.html file.