I am getting a file table overflow issue while running the Karma tests, and I have no clue how to debug this.
karma.conf.js:
module.exports = function (config) {
config.set({
frameworks: ['jspm', 'jasmine'],
files: [
'node_modules/karma-babel-preprocessor/node_modules/babel-core/browser-polyfill.js',
'node_modules/jasmine-async-sugar/jasmine-async-sugar.js'
],
jspm: {
config: 'jspm.conf.js',
loadFiles: ['src/app/app.js', 'src/app/**/*.spec.js'], //'src/app/**/!(*.e2e|*.po).js'
serveFiles: ['src/app/**/*.+(js|html|css|json)'] // *.{a,b,c} to *.+(a|b|c) https://github.com/karma-runner/karma/issues/1532
},
proxies: {
'/test/': '/base/test/',
'/src/app/': '/base/src/app/',
'/jspm_packages/': '/base/jspm_packages/'
},
//reporters: process.argv.slice(2).find((argv) => argv.includes('--nocoverage') || argv.includes('--no-coverage')) ? ['dots', 'junit'] : ['dots', 'junit', 'coverage'],
// use dots reporter, as Travis terminal does not support escaping sequences;
// when using Travis publish coverage to coveralls
reporters: coveralls ? ['dots', 'junit', 'coverage', 'coveralls'] : nocoverage ? ['dots'] : ['dots', 'junit', 'coverage'],
junitReporter: {
outputDir: 'test-reports/unit-test-report/',
suite: 'unit'
},
preprocessors: {
// source files, that you wanna generate coverage for - do not include tests or libraries
// (these files will be instrumented by Istanbul)
'src/**/!(*.spec|*.mock|*-mock|*.e2e|*.po|*.test).js': ['babel', 'coverage']
},
// transpile with babel since the coverage reporter throws error on ES6 syntax
babelPreprocessor: {
options: {
stage: 1,
sourceMap: 'inline'
}
},
coverageReporter: {
instrumenters: { isparta : require('isparta') },
instrumenter: {
'src/**/*.js': 'isparta'
},
dir: 'test-reports/coverage/',
subdir: normalizationBrowserName,
reporters: [
{type: 'html'}, // will generate html report
{type: 'json'}, // will generate json report file and this report is loaded to make sure failed coverage cause gulp to exit non-zero
{type: 'lcov'}, // will generate Icov report file and this report is published to coveralls
{type: 'text-summary'} // it does not generate any file but it will print coverage to console
]
},
browsers: [process.env.TRAVIS ? 'Firefox' : 'Chrome'],
browserNoActivityTimeout: 50000
});
function normalizationBrowserName(browser) {
return browser.toLowerCase().split(/[ /-]/)[0];
}
};
package.json:
"karma": "0.13.14",
"karma-jspm": "2.0.1",
"karma-jasmine": "0.3.6",
"karma-coverage": "douglasduteil/karma-coverage#next",
"karma-coveralls": "1.1.2",
"karma-ie-launcher": "0.2.0",
"karma-junit-reporter": "0.3.8",
"karma-chrome-launcher": "0.2.1",
"karma-safari-launcher": "0.1.1",
"karma-firefox-launcher": "0.1.6",
"karma-phantomjs-launcher": "0.2.1",
"karma-babel-preprocessor": "5.2.2"
test-unit.js:
gulp.task('karma', (cb) => {
// remove 'coverage' directory before each test
del.sync(path.test.testReports.coverage);
// run the karma test
const server = new Server({
configFile: path.test.config.karma,
browsers: BROWSERS.split(','),
singleRun: !argv.watch,
autoWatch: !!argv.watch
}, function(code) {
// make sure failed karma tests cause gulp to exit non-zero
if(code === 1) {
LOG(COLORS.red('Error: unit test failed '));
return process.exit(1);
}
cb();
});
server.start();
});
Error:
[08:44:36] 'karma' errored after 2.48 s [08:44:36] Error: ENFILE: file
table overflow, scandir '/Users/Abhi/Documents/projects/test/src/app'
at Error (native) at Object.fs.readdirSync (fs.js:808:18) at
GlobSync._readdir
(/Users/Abhi/Documents/projects/test/node_modules/karma/node_modules/glob/sync.js:275:41)
at GlobSync._processGlobStar
(/Users/Abhi/Documents/projects/test/node_modules/karma/node_modules/glob/sync.js:330:22)
at GlobSync._process
(/Users/Abhi/Documents/projects/test/node_modules/karma/node_modules/glob/sync.js:128:10)
at new GlobSync
(/Users/Abhi/Documents/projects/test/node_modules/karma/node_modules/glob/sync.js:46:10)
at new Glob
(/Users/Abhi/Documents/projects/test/node_modules/karma/node_modules/glob/glob.js:111:12)
at
/Users/Abhi/Documents/projects/test/node_modules/karma/lib/file-list.js:161:14
at Array.map (native) at [object Object].List._refresh
(/Users/Abhi/Documents/projects/test/node_modules/karma/lib/file-list.js:153:37)
at [object Object].List.refresh
(/Users/Abhi/Documents/projects/test/node_modules/karma/lib/file-list.js:252:27)
at [object Object].Server._start
(/Users/Abhi/Documents/projects/test/node_modules/karma/lib/server.js:177:12)
at [object Object].invoke
(/Users/Abhi/Documents/projects/test/node_modules/karma/node_modules/di/lib/injector.js:75:15)
at [object Object].Server.start
(/Users/Abhi/Documents/projects/test/node_modules/karma/lib/server.js:101:18)
at Gulp.
(/Users/Abhi/Documents/projects/test/gulp/tasks/test-unit.js:53:12) at
module.exports
(/Users/Abhi/Documents/projects/test/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:34:7)
at Gulp.Orchestrator._runTask
(/Users/Abhi/Documents/projects/test/node_modules/gulp/node_modules/orchestrator/index.js:273:3)
at Gulp.Orchestrator._runStep
(/Users/Abhi/Documents/projects/test/node_modules/gulp/node_modules/orchestrator/index.js:214:10)
at Gulp.Orchestrator.start
(/Users/Abhi/Documents/projects/test/node_modules/gulp/node_modules/orchestrator/index.js:134:8)
at
/Users/Abhi/Documents/projects/test/node_modules/gulp/bin/gulp.js:129:20
at nextTickCallbackWith0Args (node.js:419:9) at process._tickCallback
(node.js:348:13)
Karma Issue Tracker: https://github.com/karma-runner/karma/issues/1979
Abhi,
I spent a good afternoon on this and found a workaround, to what i have admit is a best guess issue that i have zero idea WHY is happening.
My issue was with the globs inside of serveFiles and loadFiles in the Karma config. To fix i did my own globbing using glob.sync to generate the arrays as i needed and this WORKED!
module.exports = function(config) {
var options = {cwd:"www"};
var glob = require("glob");
var filesToServe = glob.sync("./src/**/*.#(js|ts|css|scss|html)", options);
var specsToLoad = glob.sync("./src/**/*.#(spec.ts)", options).map(function(file){
return file.substr(2);
});
config.set({
basePath: 'www',
frameworks: ['jspm', 'jasmine'],
jspm: {
config: './test/config.js',
loadFiles: ['test/boot.ts'].concat(specsToLoad),
serveFiles: filesToServe,
},
files: [
'http://cdn.auth0.com/js/lock-8.2.min.js'
],
proxies: {
'/src/': '/base/src/',
'/.test/': '/base/.test/'
},
port: 9876,
logLevel: config.LOG_DISABLE,
colors: true,
autoWatch: true,
browsers: ['Chrome'],
plugins: [
'karma-jspm',
'karma-jasmine',
'karma-chrome-launcher',
'karma-spec-reporter'
],
reporters: ['spec'],
singleRun: true
});
};
The filesToServe and specsToLoad are treated slightly differently, i needed to remove the ./ from the files to load as it interferes with SystemJS's loading internally (this can be recognised by it trying to load a .ts.js file). Also i've got my work in a sub folder, 'www' which you might not need e.g. remove the cwd.
Hopefully you can see what i've done here and it helps you find a workaround. If anyone knows why something like glob is breaking i'd love to know.
To prove it was glob i did a simple test, using
require(glob)("src/**/*",function(file){ console.log(file); });
This triggered the same error, clearly NOTHING to do with too many files or a file table issue. If this pops up in other places, i'm going to have to clean install the OS again i think. However in my code base i use globs in other places, without any issue. I had wondered if it perhaps was the difference between using the 'sync' version of the process...
A day of wading through options to end up here... i had hoped to find a better answer.
K
Related
I'm trying to write tests for m nodejs simple application with karma and jasmine as a framework. I'm using karma-coverage for preprocessor.
Here is the structure of the project:
package.json
{
"name": "tests",
"version": "1.0.0",
"description": "tests with karma in jasmine framework",
"directories": {
"test": "test"
},
"scripts": {
"test": "karma start karma.conf.js"
},
"author": "",
"license": "MIT",
"devDependencies": {
"jasmine-core": "^3.4.0",
"karma": "^4.2.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^1.1.2",
"karma-jasmine": "^2.0.1"
}
}
karma.conf.js
// Karma configuration
// Generated on Sat Aug 17 2019 09:37:53 GMT+0500 (Uzbekistan Standard Time)
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'],
// list of files / patterns to load in the browser
files: [
'js/*.js',
'test/*.test.js'
],
// list of files / patterns to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'test/*.test.js': ['coverage']
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// 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,
// optionally, configure the reporter
coverageReporter: {
type: 'html',
dir: 'coverage/'
}
})
}
Whenever I run npm test I'm getting the following error:
custom-lodash.js
class CustomLodash {
compact(array) {
let newArray = [];
for (let i = 0; i < array.length; i++) {
if (!array[i] || array[i] === undefined || array[i] === null) {
continue;
}
this.push(array[i])(newArray);
}
return newArray;
}
}
let _ = new CustomLodash;
module.exports = {
compact: _.compact
};
custom-lodash.test.js
describe("CustomLodash", function () {
let utils;
//This will be called before running each spec
beforeEach(function () {
console.log('before each');
utils = new CustomLodash();
});
describe("when calc is used to peform basic math operations", function () {
it("creates an array with all falsey values removed", function () {
// expect(utils.compact([0, 1, false, 2, '', 3])).toBe([1, 2, 3]);
let compact = utils.compact([0, 1, false, 2, '', 3]);
console.log('before each in it is: ', compact);
expect(compact).toEqual([1, 2, 3]);
//console.log('is defined ', expect(compact).toEqual([1, 2, 3]));
});
})
});
As you can see, the console.log is giving output, which means the file is being read. But, when I call toBe() or toEqual() I can see that the output is undefined (checked this in console.log too).
Any help is really appreciated. I searched for many answers and realted questions, but can't fix this one.
I want to share with my solution to this case.
Adding browserify worked for me. Also, I added watchify to watch files for incremental compilation.
Browserify was born to make your Node code in the browser. Till date
it only supports the node flavour of commons (including JSON support)
and provides in-built shims for many node core modules. Everything
else is a different package.
Here is how my package.json looks like after adding packages to run my ES6 code both in browser and Node:
"dependencies": {
"browserify": "^16.2.3",
"jasmine-core": "^3.2.1",
"karma": "^4.2.0",
"karma-chrome-launcher": "^3.1.0",
"karma-browserify": "^5.3.0",
"karma-commonjs": "^1.0.0",
"karma-coverage": "^1.1.2",
"karma-jasmine": "^2.0.1"
"watchify": "^3.11.0"
}
Don't forget to add browserify in your karma.config.js configuration as follows:
add it to your frameworks list
add it your preprocessors list.
Example:
preprocessors: {
'src/**/*.js': ['coverage'],
'js/**/*.js': ['browserify'],
'test/**/*.[sS]pec.js': ['browserify']
}
One can solve this kind of problem with ES6 by building webpack, but as browserify is much more likely to work with minimal configuration I chose using it as a solution in this situation. Hope it will help someone.
I have some test files with tests I'd like to run against my app.
I am attempting to use karma, karma-webpack, karma-babel-preprocessor, karma-chrome-launcher, and jasmine in my testing. My app depends on many things, including backbone, marionette, etc. My app is built using webpack, and I am attempting to use webpack to bundle my files together for testing. (I initially wanted to see if I could skip this step, i.e. simply import a file to be tested, but it seems this is impossible.)
My test script looks like
package.json (scripts section)
"test": "./node_modules/karma/bin/karma start",
The rest of the files:
karma.conf.js
var webpackConfig = require('./config/webpack/webpack.test.conf.js');
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
{ pattern: 'test/**/*.spec.js', watched: true },
{ pattern: 'test/*.spec.js', watched: true }
],
exclude: [
],
preprocessors: {
'test/**/*.spec.js': ['webpack'],
'test/*.spec.js': ['webpack']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
concurrency: Infinity
})
}
test/test.spec.js This file is seen
describe("A suite", function () {
it("contains spec with an expectation", function () {
expect(true).toBe(true);
});
});
describe("Another suite", function () {
it("contains another spec with an expectation", function () {
expect(true).toBe(false);
});
});
test/models/devicegroup.spec.js This file is not seen
import backbone from 'backbone';
describe("backbone", function () {
it("containsasdfasdfasdfasdfspec with an expectation", function ()
{
expect(true).toBe(false);
});
});
My folder structure is:
- karma.conf.js
- test/
- - test.spec.js
- - models/
- - - devicegroup.spec.js
- public/
- - js/
- - - app.js
When my files don't have import statements at the top, karma will run and pass/fail as expected. Putting an import statement at the top will cause karma to ignore the file. No errors are thrown.
How can I make karma / karma-webpack run my tests that have import statements / what is the karma-safe way to import modules into my tests?
When test/models/devicegroup.spec.js does not have an import statement:
// import backbone from 'backbone';
describe("backbone", function () {
it("contains with an expectation", function () {
expect(true).toBe(false);
});
});
the terminal output is: (notice one less test is run)
When test/models/devicegroup.spec.js does have an import statement:
import backbone from 'backbone';
describe("backbone", function () {
it("contains with an expectation", function () {
expect(true).toBe(false);
});
});
the terminal output is:
I see no errors in the browser Karma opens.
EDIT:
I have experimented by adding my source files to the files and preprocessors attributes in my karma.conf.js file, as per this repo example. There was no change in behavior other than a massively increased testing time.
karma.conf.js
files: [
{ pattern: 'public/js/**/*.js', watched: true},
{ pattern: 'test/**/*.spec.js', watched: true },
// each file acts as entry point for the webpack configuration
],
preprocessors: {
// add webpack as preprocessor
'public/js/**/*.js': ['webpack'],
'test/**/*.spec.js': ['webpack'],
},
EDIT2:
For the sake of experimentation (and based off this person's struggles), I have tried the above karma.conf.js in every possible combination - only test files in files and preprocessors, only source files, test files in one but not the other, source files in one but not the other, none, both. No good results, though occasionally new errors.
Little late, but I ran into the same problem, and was searching for hours, why my imports prevent the test suite from being executed. karma-webpack-4.0.0-rc.2 brought the enlightenment by providing error messages!!
I my case a couple of modules where not found, angular-mock, jquery, angular and more.
How to fix
Put there modules into the files array in your karma.config like:
files = [
"node_modules/jquery/dist/jquery.js",
"node_modules/angular/angular.js",
"node_modules/angular-mocks/angular-mocks.js",
{ pattern: "test/**/*.ts", watched: false }
I hope, this helps someone.
EDIT
My current versions of the testing related packages:
"#types/jasmine": "^2.8.8",
"jasmine": "^3.2.0",
"jasmine-core": "^3.2.1",
"jasmine-reporters": "2.3.2",
"jasmine-ts": "^0.2.1",
"karma": "3.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-jasmine": "1.1.2",
"karma-junit-reporter": "1.2.0",
"karma-phantomjs-launcher": "1.0.4",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.32",
"karma-webpack": "^4.0.0-rc.2",
"typescript": "3.0.3",
"webpack": "4.17.2",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "3.1.8"
I'm trying to test (with coverage) my TypeScript application using Karma, Jasmine, and Webpack. With the following, I'm able to successfully run tests, but am unable to generate coverage properly. I'm using karma-remap-coverage (https://github.com/sshev/karma-remap-coverage) and it seems simple enough.
It looks as though something interesting is happening (and I'm getting some kind of coverage report) but with a few tweaks here and there, the numbers change drastically and I can never actually load the sourcemaps.
Here's the basic setup:
I have a src directory that contains 10 .ts files. Only one has a corresponding .spec file at the moment.
The spec file is pretty simple and was just enough to prove that I could run tests:
import ComponentToTest from './componentToTest';
describe('ComponentToTest', () => {
it('should run a test', () => {
expect(1+1).toBe(2);
});
it('should be able to invoke the a method', () => {
spyOn(ComponentToTest, 'foo').and.callThrough();
ComponentToTest.foo('testing foo');
expect(ComponentToTest.foo).toHaveBeenCalled();
});
});
This works like a charm when paired with my tsconfig.json file:
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"noImplicitAny": false,
"sourceMap": true,
"lib": ["es6", "dom"],
"experimentalDecorators": true
},
"exclude": [
"node_modules"
]
}
and karma.conf.js file:
module.exports = config => config.set({
frameworks: ['jasmine'],
mime: { 'text/x-typescript': ['ts','tsx'] },
// if I make this a generic './src/**/*.ts' it seems to freeze up
// without throwing any errors or running any tests, but that seems
// like a separate issue...
files: [
'./src/lib/componentToTest.ts',
'./src/lib/componentToTest.spec.ts'
],
preprocessors: {
'./src/**/*.spec.ts': ['webpack'],
'./src/**/*.ts': ['webpack', 'sourcemap', 'coverage']
},
webpack: {
devtool: "source-map",
module: {
rules: [
{
test: /\.ts?$/,
loader: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: [".ts", ".js"]
}
},
webpackMiddleware: {
quiet: true,
stats: {
colors: true
}
},
// add both "karma-coverage" and "karma-remap-coverage" reporters
reporters: ['progress', 'coverage', 'remap-coverage'],
// save interim raw coverage report in memory
coverageReporter: {
type: 'in-memory'
},
// define where to save final remaped coverage reports
remapCoverageReporter: {
'text-summary': null,
html: './coverage/html',
cobertura: './coverage/cobertura.xml'
},
colors: 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: true
});
And finally, I'm launching the tests with a simple Gulp task:
gulp.task('test', function (done) {
new Server({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, (exitCode) => {
done();
process.exit(exitCode);
}).start();
});
When run, I get an output that seems (mostly) promising:
Chrome 58.0.3029 (Mac OS X 10.12.3): Executed 1 of 2 SUCCESS (0 secs / 0.002 secs)
Chrome 58.0.3029 (Mac OS X 10.12.3): Executed 2 of 2 SUCCESS (0.026 secs / 0.004 secs)
[Error: Could not find source map for: "app/src/lib/componentToTest.ts"]
[Error: Could not find source map for: "app/src/lib/componentToTest.spec.ts"]
========================= Coverage summary =========================
Statements : 43.69% ( 322/737 )
Branches : 15.7% ( 38/242 )
Functions : 35.47% ( 61/172 )
Lines : 44.91% ( 322/717 )
====================================================================
So something is happening! Which makes me feel like I'm close. When I browse to my coverage report in a browser, I see both the .spec.ts file and the .ts file listed (which is again, getting closer) but I'm not quite there for a couple of reasons:
The .spec.ts file is being included in the coverage report. Since this is the test file, I do not want to include it.
Source maps are not being properly generated - this is clear from the errors in the console and also from the inability to browse to the specific file's coverage report.
I do feel like I'm pretty darn close. Is there anything simple that I'm missing or suggestions?
Update:
I realized I was using an older version of Node and thought that may be causing some issues. I upgraded to 6.11.0 and while that didn't solve anything, it did provide slightly more context:
The errors are being reported by remap-istanbul (no surprise there, really):
CoverageTransformer.addFileCoverage (/app/node_modules/remap-istanbul/lib/CoverageTransformer.js:148:17)
I am using karma-remap-coverage#0.1.4 which uses remap-istanbul#0.8.4 - it seems like there have been issues with remap-istanbul in the past, but not at the version I'm using.
Also using Webpack 2.6.1 and TypeScript 2.3.2
Well, after several days of trying different things, I've finally found a solution that works. I'm not sure specifically what was causing the issue in my first post, but here's where I've ended up. This may be helpful for someone else looking for a really simple TypeScript, Karma, Jasmine, Webpack (with coverage) setup.
My file structure and spec file stayed the same.
My tsconfig.json updated to:
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"noImplicitAny": false,
"inlineSourceMap": true, // this line
"sourceMap": false, // and this one
"experimentalDecorators": true,
"lib": ["es6", "dom"]
},
"exclude": [
"node_modules"
]
}
I switched to using the awesome-typescript-loader instead of ts-loader.
And finally, my karma.conf.js file now looks like:
module.exports = config => config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
frameworks: ['jasmine'],
mime: { 'text/x-typescript': ['ts','tsx'] },
files: [
'node_modules/angular/angular.min.js',
'./src/**/*.ts'
],
preprocessors: {
'./src/**/*.ts': ['webpack']
},
webpack: {
devtool: 'inline-source-map',
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
exclude: [
'node_modules',
/\.spec\.ts$/
]
},
{
test: /\.ts?$/,
use: [
{
loader: 'awesome-typescript-loader',
query: {
/**
* Use inline sourcemaps for "karma-remap-coverage" reporter
*/
sourceMap: false,
inlineSourceMap: true,
compilerOptions: {
removeComments: true
}
},
}
]
},
{
enforce: 'post',
test: /\.(js|ts)$/,
loader: 'istanbul-instrumenter-loader',
exclude: [
/node_modules/,
/\.spec\.ts$/
]
},
{ test: /\.html$/, loader: 'html-loader' }
]
},
resolve: {
extensions: [".ts", ".js", ".html"]
},
externals: {
angular: "angular"
}
},
webpackMiddleware: {
quiet: true,
stats: {
colors: true
}
},
// add both "karma-coverage" and "karma-remap-coverage" reporters
reporters: ['progress', 'coverage', 'remap-coverage'],
// save interim raw coverage report in memory
coverageReporter: {
type: 'in-memory'
},
// define where to save final remaped coverage reports
remapCoverageReporter: {
'text-summary': null,
html: './coverage/html',
cobertura: './coverage/cobertura.xml'
},
colors: 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: true
});
Final package versions include:
node 4.2.6 (I was also able to get this to work with a newer version of node, but need to be here for other reasons)
awesome-typescript-loader 3.1.2
istanbul-instrumenter-loader 2.0.0
jasmine-core 2.5.2
karma 1.6.0
karma-chrome-launcher 2.0.0
karma-coverage 1.1.1
karma-jasmine 1.1.0
karma-remap-coverage 0.1.4
karma-webpack 2.0.3
typescript 2.3.2
webpack 2.6.1
Now my tests run, there are no errors in the console, and I have a coverage report of the original TypeScript files!
Lots of credit to the folks who put this together (it ended up guiding quite a bit of my final solution): https://github.com/AngularClass/angular-starter/tree/master/config
I am trying to unit test (with Karma + Jasmine + karma-typescript) my TypeScript project. The project structure is as follows:
root
|- src/*.ts //all TypeScript source files
|- tests/unit/*.spec.ts //all spec (test) files
|- karma.conf.js
|- tsconfig.json
My karma.conf.js looks like following:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', "karma-typescript"],
karmaTypescriptConfig: {
tsconfig: "./tsconfig.json"
},
files: [
'src/*.ts',
'tests/**/*Spec.ts'
],
exclude: [],
preprocessors: {
"**/*.ts": ["karma-typescript"]
},
reporters: ["progress", "karma-typescript"],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
concurrency: Infinity
})
}
My spec file looks like below:
import 'aurelia-polyfills'; //<- importing this, as the project have dependency on Aurelia
// import "babel-polyfill";
import "reflect-metadata";
import "jasmine";
import { Utility } from './../../src/Utility';
describe("this is a try to set up karma-jasmine-webpack test (TS)", () => {
it("utility_test", () => {
const result = Utility.doSomething();
const expected = Expected_Result;
expect(result).toEqual(expected);
});
});
But when I run karma start, I get
Chrome 55.0.2883 (Windows 10 0.0.0) ERROR
Uncaught TypeError: Reflect.getOwnMetadata is not a function
at C:/Users/spal/AppData/Local/Temp/karma-typescript-bundle-16376WqjdFvsYtjdI.js:2325
I assume, that it is because of pollyfill(s) is/are not being loaded in the browser. However, I have imported aurelia-pollyfills in my spec file.
Please suggest how this can be corrected.
Update: Anyone looking at this for answer, might also face issues with source map (Error: Could not find source map for:'') from karma-remap-istanbul trying to generate coverage report.
One way to avoid this problem is to simply remove the problematic reporter plugin. For example, change reporters: ['mocha', 'coverage', 'karma-remap-istanbul'] to reporters: ['mocha', 'coverage'].
Other solution would be to generate the source maps. In case you can't specify the same in your tsconfig.json, you can specify that in karma.conf.js if you are using karma-typescript:
karmaTypescriptConfig: {
tsconfig: "./tsconfig.json",
compilerOptions: {
sourceMap: true
}
}
Lastly, I ended up with reporters: ["mocha", "karma-typescript"], as it shows which test passed, and which failed, as well as generate a coverage report.
You are probably missing the reflect-metadata import:
$ npm install --save-dev reflect-metadata
Then add the following to your files:
files: [
{ pattern: "node_modules/reflect-metadata/Reflect.js", include: true },
{ pattern: "src/*.ts", include: true },
{ pattern: "tests/**/*Spec.ts", include: true }
]
I'm using Karma + Mocha to run my unit tests, everything works pretty well except whenever the tests fails,
When I run a test like
expect(player).to.be.an('object');
and it fails I would expect it to say that "Object was expected but string given" or something like that, Instead all I get is (for every single failed test, no matter how it fails, even when I try to asset true with false):
SyntaxError: Unexpected token N
at Object.parse (native)
at Array.map (native)
I know for a fact that there's no syntax errors in my code, so Im guessing that's something to do with karma/mocha and the way they handle the failed tests.. I just dont know where to look.. here is my gulp task:
var karmaServer = require('karma').server;
gulp.task('test', function (done) {
gutil.log('preparing tests.');
var runOnlyOnce = true;
// check if a parameter named "watch" is passed. if so - run tests in watch mode.
if (argv.watch){
runOnlyOnce = false;
}
if (runOnlyOnce){
gutil.log('Running only once.\nTo run in "watch" mode try: gulp test --watch');
} else {
gutil.log('Running in watch mode. Oh yeah.');
}
karmaServer.start({
configFile: __dirname +'/karma.conf.js',
singleRun: runOnlyOnce
}, function(exitCode) {
gutil.log('Karma has exited with ' + exitCode);
if (exitCode != 0){
gutil.log(gutil.colors.bgRed("Test(s) failed."));
}
process.exit(exitCode);
});
});
Here is my karma.conf file:
module.exports = function (config) {
'use strict';
config.set({
basePath: '',
frameworks: ['browserify', 'mocha', 'source-map-support'],
// reporters configuration
reporters: ['mocha'],
preprocessors: {
'test/**/*.spec.js': ['browserify']
},
files: [
{pattern: 'app/**/*.js', watched: true, included: false, served: false}, // watch these files, but dont bundle them for tests
'test/**/*.spec.js'
],
browserify: {
debug: true,
transform: ['babelify']
},
plugins: [
'karma-mocha-reporter',
'karma-mocha',
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-browserify',
'babel-plugin-espower',
'karma-ie-launcher',
'karma-source-map-support'
],
port: 9876,
colors: true,
usePolling: true,
atomic_save: false,
autoWatch : true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
browsers: ["Chrome"] //, "IE", 'PhantomJS'
});
};
Any help would be much appreciated!!! Thank you!
So I found the problem, all I did was to remove the debug flag from the karma.conf file..
instead of
browserify: {
debug: true,
transform: ['babelify']
},
I did:
browserify: {
debug: false,
transform: ['babelify']
},
that did the trick.
I hope this helps anyone! cheers!