Jest - Cannot generate cobertura coverage report for my projects - jestjs

I'm using jest in a monorepo. I would like to generate a Cobertura report when testing a some of my projects.
Jest.config.base.js
module.exports = {
preset: '#vue/cli-plugin-unit-jest/presets/typescript-and-babel',
transform: {
'vee-validate/dist/rules': 'babel-jest',
'.*\\.(vue)$': 'vue-jest',
'^.+\\.(ts|tsx)$': 'ts-jest',
},
testMatch: [
'**/*.(spec|test).(js|jsx|ts|tsx)',
],
testEnvironmentOptions: {
// Allow test environment to fire onload event
// See https://github.com/jsdom/jsdom/issues/1816#issuecomment-355188615
resources: 'usable',
},
reporters: [
'default',
[
'jest-trx-results-processor',
{
outputFile: './coverage/test-results.trx',
defaultUserName: 'user name to use if automatic detection fails',
},
],
],
moduleFileExtensions: [
'js',
'ts',
'json',
'vue',
],
testURL: 'http://localhost/',
snapshotSerializers: [
'jest-serializer-vue',
],
runner: 'groups',
};
Jest.config (root)
const baseConfig = require('./jest.config.base')
module.exports = {
...baseConfig,
projects: [
'<rootDir>/apps/my-app',
'<rootDir>/apps/my-app-copy',
'<rootDir>/libs/my-lib',
],
coverageDirectory: '<rootDir>/coverage/',
};
Jest.config (my-app)
const baseConfig = require('../../jest.config.base');
const packageJson = require('./package.json');
module.exports = {
...baseConfig,
transformIgnorePatterns: [],
roots: [
'<rootDir>/src',
],
name: packageJson.name,
displayName: packageJson.name,
};
I did not paste other jest.config to save space, but they are similar.
What works
If I run jest --coverage --coverageReporters=cobertura, it will generate a Cobertura report, but all my projects will be tested.
What does not work
If I run jest --projects apps/my-app apps/my-app-copy --coverage --coverageReporters=cobertura, only test-results.trx is generated.
Question
How could I test only 2 projects out of 3, and generate a single Cobertura report for those?

I'm working on something similar in our monorepo and I was able to generate the cobertura report installing jest-junit and defining the reporters in the root jest.config like this
coverageReporters: ['html', 'text', 'text-summary', 'cobertura'],
Then I run jest --coverage

Related

babel-jest: Babel ignores app/utils/myfile.js - make sure to include the file in Jest's transformIgnorePatterns as well

I cannot get my jest tests to run when I have ignored a file with babel:
babel.config.js:
module.exports = {
ignore: ['./app/utils/myfile.js'],
presets: [
[
'#babel/preset-env',
{
targets: {
node: '14',
},
useBuiltIns: 'entry',
corejs: '3.8',
},
],
],
};
jest.config.js:
module.exports = {
coverageDirectory: 'coverage',
setupFiles: ['./jest.init.js'],
testEnvironment: 'node',
testMatch: ['**/?(*.)+(spec|test).js'],
transform: {
'^.+\\.(js|jsx)$': 'babel-jest',
},
transformIgnorePatterns: ['myfile'],
testPathIgnorePatterns: ['/node_modules/'],
};
i have added myfile.js to the babel ignore and to the jest transformIgnorePatterns. what could it be?

jest coverageDirectory configuration for project inside monorepo

I have a typescript monorepo with jest. Their jest.config.js is
module.exports = {
clearMocks: true,
projects: ['<rootDir>/packages/**/jest.config.js'],
collectCoverage: true,
coverageReporters: [
"text-summary",
"lcov",
],
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['*.spec.ts', '*.spec.tsx']
}
At the server package I create the jest.config.js with
const { name } = require('./package.json');
module.exports = {
displayName: name,
name,
'transform': {
'^.+\\.ts$': 'ts-jest'
},
collectCoverageFrom: [
'<rootDir>/src/**/*.ts'
],
coverageDirectory: '<rootDir>/packages/server/src/tests/coverage',
}
But when I run jest it creates the coverage directory at the root of my monorepo.
I just try to use coverageDirectory: '<rootDir>/src/tests/coverage',, coverageDirectory: 'src/tests/coverage', and coverageDirectory: [__dirname, 'src', 'tests', 'coverage'].join('/'), without success.
The only way I could change the path of coverage directory was to specify it at the jest.config.js of the monorepo, but with this I am unable to specify a coverage directory to each project.
Somebody knows how can I specify a different coverage directory for each project at a monorepo?
You can only specify a different coverage directory for each project if you are running jest for each product individually. If you are using a global config (the jest.config.js at the root of your monorepo) then the same coverage settings are applied across them all, including the coverage output directory.

karma Uncaught SyntaxError: Unexpected token export

I use karma + jasmine to write test cases for vue and webpack, and it once worked. But after I upgrade vue for 1 to 2, and update vue-loader accordingly, it starts to give error.
Now when I run karma start karma.config.js, it give me error like:
Chrome 53.0.2785 (Windows 7 0.0.0) ERROR
Uncaught SyntaxError: Unexpected token export
at test/index.js:8995
My karma.config.js is:
var webpackConf = require('./webpack.config.js')
delete webpackConf.entry
module.exports = function (config) {
config.set({
browsers: ['Chrome'],
frameworks: ['jasmine'],
reporters: ['progress', 'html'],
htmlReporter: {
outputFile: 'tests/unit-test.html',
// Optional
pageTitle: 'Unit Tests',
subPageTitle: 'A sample project description',
groupSuites: true,
useCompactStyle: true,
useLegacyStyle: true
},
// this is the entry file for all our tests.
files: [
{pattern: './test/index.js', watched: false},
],
// we will pass the entry file to webpack for bundling.
preprocessors: {
'./test/index.js': ['webpack']
},
// use the webpack config
webpack: webpackConf,
// avoid walls of useless text
webpackMiddleware: {
noInfo: true
},
singleRun: true,
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-webpack',
'karma-htmlfile-reporter'
]
})
}
My webpack.config.js is:
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require('webpack');
module.exports = {
entry: ['webpack-hot-middleware/client','./index.js'],
output: {
path: path.resolve(__dirname, '../output/static'),
publicPath: '/',
//filename: '[name].[hash].js'
filename: 'main.js'
//chunkFilename: '[id].[chunkhash].js'
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.common.js'
},
extensions: ['', '.js', '.vue']
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue'
},
{
test: /\.js$/,
loader: 'babel?presets=es2015',
exclude: /node_modules/
},
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
}
]
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, 'index.html'),
inject: true
})
]
}
Looks like the es6 export syntax is not translated correctly. Also, I did not know where to take a look at the test/index.js:8995 because this is auto generated by webpack. The real index.js is quite simple, just 2 lines:
var testsContext = require.context('.', true, /\.spec\.js$/)
testsContext.keys().forEach(testsContext)
How to debug this and what can I do to solve the problem?

What's the proper way to set NODE_ENV in Karma for running webpack?

I'm building my project with Webpack and using Karma for running tests.
I want to configure Karma to set process.env.NODE_ENV to "test" for Webpack to perform conditional build of the project for testing environment with URLs mapped to localhost, not production domain name.
For that purpose I make use of Webpack's env-replace-loader, which reads its configuration file environments.json and sets variables, such as API_URL, depending on the values of process.env.NODE_ENV. In production build I use Gulp to set process.env.NODE_ENV and start webpack. It works.
I want to set process.env.NODE_ENV = 'test' in testing build, initiated by running karma start karma.conf.js. Currently I just say process.env.NODE_ENV = "test" in karma.conf.js.
Is there a better way to do that?
Besides, I tried to use DefinePlugin of webpack in webpack.config.js to set this variable like this:
const webpackConfig = {
...
plugins: [
new webpack.DefinePlugin({
process.env: {'NODE_ENV': 'test'}
}),
...
],
...
}
and it won't work: webpack env-replace-loader curses that Module build failed: TypeError: Cannot read property 'URL' of undefined - I suppose, it can not access the node reports that it doesn't see
In your webpack config try this JSON.stringify('name') instead. Try something like this:
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
APP_ENV: JSON.stringify('browser')
},
})
],
That works with the webpack running a example or something like that. For example, I'm using that to require CSS when running an example but it get ignored when compiling for production.
I got the same problem with Karma config but I fix that adding the plugin into the webpack part of the Karma config file. It's my file for example:
const webpack = require('webpack');
module.exports = function(config) {
config.set({
browsers: ['PhantomJS'],
files: [
'tests.webpack.js',
{
pattern: 'src/**/__tests__/*.js',
included: false,
served: false,
watched: true
}
],
frameworks: ['jasmine'],
preprocessors: {
'tests.webpack.js': ['webpack', 'sourcemap', 'coverage'],
},
reporters: ['progress', 'notification'],
webpack: {
devtool: 'inline-source-map',
module: {
loaders: [
{ test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader' }
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('test')
}
})
],
watch: true
},
webpackServer: {
noInfo: true,
}
});
};
I hope that's helpfull for you too!

karma-browserify coverage reports contain file include paths instead of source code

Using karma-browserify to do unit tests with Jasmine. The tests correctly run but the coverage reports show file include paths instead of source code. You can reproduce this by installing the following project and run 'gulp unit':
https://github.com/bshack/shackstack
Here is an example of the coverage report contents:
typeof require === "function" && require("/xxx/xxx/xxx/shackstack/app/media/script/service/utilities.js");
Here is my karma.config:
module.exports = function(karma) {
'use strict';
karma.set({
basePath: '',
frameworks: [
'jasmine',
'browserify'
],
files: [{
pattern: 'app/media/script/service/*.js',
included: true
},
{
pattern: 'app/media/test/spec/*Spec.js',
included: true
}],
reporters: [
'progress',
'coverage'
],
preprocessors: {
'app/media/script/service/*.js': [
'browserify',
'coverage'
],
'app/media/test/spec/*Spec.js': [
'browserify'
]
},
browsers: [
//'Chrome',
//'Firefox',
//'Safari',
'PhantomJS'
],
singleRun: false,
autoWatch: false,
// browserify configuration
browserify: {
debug: true,
transform: [
'brfs',
'browserify-shim'
]
},
coverageReporter: {
type: 'html',
dir: 'app/report/istanbul/',
subdir: '.'
},
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000
});
};
any thoughts?
Fixed, basically you don't use karma coverage as you would normally, instead you have to use istanbul as a browserify transform.
var istanbul = require('browserify-istanbul');
module.exports = function(karma) {
'use strict';
karma.set({
basePath: '',
frameworks: [
'jasmine',
'browserify'
],
files: [{
pattern: 'app/media/script/service/*.js'
},
{
pattern: 'app/media/test/spec/*Spec.js'
}],
reporters: [
'progress',
'coverage'
],
preprocessors: {
'app/media/script/service/*.js': [
'browserify'
],
'app/media/test/spec/*Spec.js': [
'browserify'
]
},
browsers: [
//'Chrome',
//'Firefox',
//'Safari',
'PhantomJS'
],
singleRun: false,
autoWatch: false,
browserify: {
debug: true,
transform: [
'brfs',
'browserify-shim',
istanbul({
ignore: ['**/node_modules/**']
})
]
},
coverageReporter: {
type: 'html',
dir: 'app/report/istanbul/',
subdir: '.'
},
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000
});
};

Resources