Angular 11 Unit Test Code Coverage is Now Breaking - unit-testing

Prior to upgrading to Angular 11, I ran my unit tests with code coverage via the following command:
ng test --project my-app --code-coverage true
When I upgraded my project to Angular 11, I was still able to do my code coverage tests, but I started getting a message saying "'karma-coverage-istanbul-reporter' usage has been deprecated since version 11". It asked me to install karma-coverage and update karma.conf.js. So I did what it asked. I installed karma-coverage and karma via this command:
npm install karma karma-coverage --save-dev
As a result, I see in my package.json, under devDependencies, the entries for karma:
"karma": "^5.2.3",<br>
"karma-coverage": "^2.0.3"
I updated my karma.conf.js file. The following is what exists, everything was as it was originally except for my comments:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'), // NEWLY ADDED
// ORIGINALLY HERE NOW REMOVED require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
reporters: ['progress', 'kjhtml', 'coverage'],
// coverageIstanbulReporter NO LONGER HERE
//coverageIstanbulReporter: {
// dir: require('path').join(__dirname, '../../coverage/my-app'),
// reports: ['html', 'lcovonly', 'text-summary'],
// fixWebpackSourcePaths: true
//},
// coverReporter NEWLY ADDED
coverageReporter: {
dir: 'build/reports/coverage',
reporters: [
{ type: 'html', subdir: 'report-html' },
{ type: 'lcov', subdir: 'report-lcov' }
]
},
// THE FOLLOWING REMAINED AS IS
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: true
});
};
Having made this update, two things are happening and I can't figure out why.
When I run my normal code coverage command, I get the following error: "Server start failed on port 9876: Error: karma-coverage must be installed in order to run code coverage." I did install it, as my package.json indicates, but for some reason my project doesn't recognize this. In addition, if I add back the karma-coverage-istanbul-reporter require method to my conf.js file, coverage works fine, but I still get that deprecation message. Can anyone explain to me why I may be getting this error?
When I run my tests without coverage, I now get multiple warnings that I never got before, like: "Unable to determine file type from the file extension, defaulting to js.
To silence the warning specify a valid type for C:/Angular/my-project/projects/my-app/src/app/app.component.spec.ts in the configuration file." What would I need to do to resolve this?
EDIT: I found the answer. Inside the coverageReporter object, you need to add the fixWebpackSourcePaths property to true:
coverageReporter: {
dir: 'build/reports/coverage',
reporters: [
{ type: 'html', subdir: 'report-html' },
{ type: 'lcov', subdir: 'report-lcov' }
],
fixWebpackSourcePaths: true
},

The trick for me was to remove 'coverage' from the reporters. It should just be:
reporters: ['progress', 'kjhtml'],
The coverage report is then created as expected without weird warnings being thrown.
This seems to be the Angular way, have a look at the karma.conf.js generated by the ng new schematics.

Also, I found that the reporters must have a subdir field:
Doesn't work
reporters: [
{ type: 'html' }
}
Doesn't work
reporters: [
{ type: 'html', subdir: '' }
}
Works:
reporters: [
{ type: 'html', subdir: 'report-html' }
}

Related

karma test suite empty from Chrome

I have a problem with setting up units tests in project. When I run tests with IE everything works fine I can see 4/4 tests executed. With chrome i am getting error Empty test suite. Chrome is launched but it looks like it can;t find tests and tests for chrome are not executed.
Karma.config.js
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', 'angular-cli'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-ie-launcher'),
require('karma-remap-istanbul'),
require('angular-cli/plugins/karma')
],
files: [
{ pattern: './src/test.ts', watched: false }
],
preprocessors: {
'./src/test.ts': ['angular-cli']
},
remapIstanbulReporter: {
reports: {
html: 'coverage',
lcovonly: './coverage/coverage.lcov'
}
},
angularCli: {
config: './angular-cli.json',
environment: 'dev'
},
reporters: ['progress', 'karma-remap-istanbul'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: true
});
};
test.ts is just searching unittests within app folder:
.then(() => require.context('./', true, /\.spec\.ts/))
I found that the issue was with reporters section, after 2 days of agony I changed file to
reporters: config.angularCli && config.angularCli.codeCoverage
? ['progress', 'karma-remap-istanbul']
: ['progress'],
removed mime section and it works!

How to Unit Test an Ionic 2 Application Tutorial Karma Error: Chrome have not captured in 60000 ms, killing

I am currently learning how to unit test in Ionic 2 using Josh Monrony's tutorial.
I am on Step 4: Create and Run a Unit Test.
When I run npm test, Chrome opens, but it never stops loading.
Then the console reports a timeout:
What is causing the timeout?
Here is my karma.conf.js file:
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'browserify'],
// list of files / patterns to load in the browser
files: [
'node_modules/es6-shim/es6-shim.js', // TypeError: undefined is not a constructor (evaluating 'new exports.Map()')
'node_modules/reflect-metadata/Reflect.js', // 'Uncaught reflect-metadata shim is required when using class decorators'
'node_modules/zone.js/dist/zone.js', // Zone.js dependencies (Zone undefined)
'node_modules/zone.js/dist/jasmine-patch.js',
'node_modules/zone.js/dist/async-test.js',
'node_modules/zone.js/dist/fake-async-test.js',
'app/**/*.spec.ts',
{pattern: 'node_modules/reflect-metadata/Reflect.js.map', included: false, served: true}, // 404 on the same
{pattern: 'www/build/**/*.html', included: false},
],
// list of files to exclude
exclude: [
'node_modules/angular2/**/*_spec.js',
'node_modules/ionic-angular/**/*spec*'
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'**/*.ts': ['browserify']
},
browserify: {
debug: true,
transform: [
['browserify-istanbul', {
instrumenter: require('isparta'),
ignore: ['**/*.spec.ts','**/*.d.ts'],
}]
],
plugin: [
['tsify']
]
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
proxies: {
'/build': '/base/www/build'
},
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
Here are similar questions, but they either don't have answers or the answers don't work:
Karma error - Chrome have not captured in 60000 ms, killing
Karma test runner - fails to capture chrome
https://github.com/karma-runner/karma/issues/1206
I had the same problem, and solved it deleting the npm directory and recreating it with npm update. That worked for me.

No Karma report on singlerun = false

I wonder if I am missing something trivial here, but I can not see any test reports if I have set up singlerun to true in karma config. It only shows that the browsers were launched and that is it. I can click on DEBUG and inspect the browser console log that way, but I would feel that one should be also see the results in the terminal too.
Thanks for the help!
My karma.config.js:
basePath: '../',
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
frameworks: ['mocha', 'chai'],
files: [
{ pattern: 'test/vendor/indexeddbshim.min.js', watched: false },
{ pattern: 'tests.webpack.js', watched: false },
],
preprocessors: {
'tests.webpack.js': ['webpack'],
},
webpack: {
resolve: {
root: [
path.resolve('./test/vendor'),
],
alias: {
backbone: 'backbone',
underscore: 'underscore',
},
},
module: {
loaders: [
{
// test: /^\.js$/,
exclude: /(node_modules|bower_components|vendor)/,
loader: 'babel-loader',
},
],
},
},
webpackServer: {
noInfo: true,
},
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
plugins: [
require('karma-webpack'),
require('karma-mocha'),
require('karma-chai'),
require('karma-phantomjs-launcher'),
require('karma-chrome-launcher'),
],
logLevel: config.LOG_INFO, });
From the comment above:
Setting singleRun: false assumes that you are explicitly start the karma-client manually.
This means that you start karma (technically the karma-server), then go to another terminal and type karma run.
Setting singleRun: true in your karma configuration will call karma run for you.
Here's the doc:
Karma configuration - requirejs version

Testing react and redux with karma and mocha

I've started working with React and Redux and I'd like to write tests for it using Karma with Mocha and PhantomJS2. I'm using the sources here as base: https://github.com/reactjs/redux/tree/master/examples/counter . I basically want to run the tests there in Karma using Phantom instead of using node and the "npm test".
I've set up and installed the required packages for karma:
package.json
"scripts": {
"test:karma": "karma start",
},
"karma": "^0.13.21",
"karma-babel-preprocessor": "^6.0.1",
"karma-mocha": "^0.2.2",
"karma-phantomjs2-launcher": "^0.5.0",
"phantomjs2": "^2.2.0",
And I've tried to figure out how to build my karma.config.js but I don't seem to get my tests to run and this is where I need the help.
karma.config.js
module.exports = function(config) {
process.env.PHANTOMJS_BIN = './node_modules/phantomjs2/lib/phantom/bin';
config.set({
basePath: './',
frameworks: ['mocha'],
plugins: [ 'karma-mocha', 'karma-phantomjs2-launcher', 'karma-babel-preprocessor' ],
files: [
"components/Counter.js",
"test/components/Counter.spec.js"
],
preprocessors: {
"components/Counter.js": ["babel"],
"test/components/Counter.spec.js": ["babel"]
},
babelPreprocessor: {
options: {
"presets": ["es2015", "react"],
}
},
reporters: ['progress'],
browsers: ['PhantomJS2'],
port: 9099,
runnerPort: 9100,
urlRoot: '/',
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
singleRun: false,
concurrency: Infinity
})
}
For react-boilerplate, we have that exact setup – take a look at our karma.conf.js and the PR that implemented Karma and let me know if that helps!

Livereload with Ember-CLI; only reload changed assets

I'm used to building a asset compilation system with Grunt or Gulp. Using Gulp's livereload and the Chrome livereload plugin, I have a pretty sweet system where it watches for changes of certain file types and reloads only the file that were changed. With ember-cli, when I change a CSS file, it just reloads the entire page, rather than just reloading the CSS file. This gets to be a pain when I'm trying to style a deeply nested process. Any ideas/thoughts on how to get this working with Ember CLI correctly?
I believe this is still a work in progress with Ember CLI and is planned for a future release, or is depending on a fix in Broccoli. See https://github.com/stefanpenner/ember-cli/issues/2371
What I've done to get around this probably isn't ideal, but I end up using grunt, and use a shell command to run ember build, copy the output to a different directory that is being served by another server (in my case IIS express), and then just manually watch my files.
Here are the snippets from my grunt file. I'm sure you can accomplish the same using Gulp.
shell: {
prod: {
command: 'ember build --environment production'
},
dev: {
command: 'ember build'
}
},
copy: {
dev: {
files: [{
src: '**',
dest: '../Server/Content/js',
cwd: 'dist/content/js',
expand: true
}, {
src: '**',
dest: '../Server/content/css',
cwd: 'dist/content/css',
expand: true
}, {
src: 'dist/index.html',
dest: '../Server/Views/Home/Root.cshtml'
}]
}
},
watch: {
dev: {
files: [
'app/**/*.js', 'app/**/*.hbs'
],
tasks: ['_buildDev'],
options: {
livereload: true
}
},
less: {
files: [
'app/**/*.less'
],
tasks: ['shell:dev', 'copy:dev']
},
css: {
files: [
'../Server/Content/css/**/*'
],
options: {
livereload: true
}
}
}
Official support is in the works, meanwhile try this ember-addon https://www.npmjs.com/package/ember-cli-styles-reloader