Karma (mocha) - Unexpected token N whenever unit test fails - javascript

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!

Related

Angular 6 Unit testing : how to use test.ts for running karma tests

Under my Angular 6 app , i ve this config
karma.conf.js:
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
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-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
mime: {
'text/x-typescript': ['ts','tsx']
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'),
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['progress', 'coverage-istanbul']
: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
browserDisconnectTimeout: 10000,
browserDisconnectTolerance: 3,
browserNoActivityTimeout: 60000,
flags: [
'--disable-web-security',
'--disable-gpu',
'--no-sandbox'
],
singleRun: true,
concurrency: Infinity
});
};
An i ve a file , test.ts ; which is supposed to configurate the test running :
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
import 'zone.js/dist/jasmine-patch';
import 'zone.js/dist/async-test';
import 'zone.js/dist/fake-async-test';
import { getTestBed } from '#angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '#angular/platform-browser-dynamic/testing';
// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
declare var __karma__: any;
declare var require: any;
// Prevent Karma from running prematurely.
__karma__.loaded = function () {};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /my-component.component.spec.ts/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
__karma__.start();
i may let me filter file to be tested
for example i want to run this one : my-component.component.spec.ts
But that it not running , and it seems that it lacks some config in the karma.conf to run the test.ts
Sugesstions ?
change this line
const context = require.context('./', true, /my-component.component.spec.ts/);
with this
const context = require.context('./', true, /my-component\.component\.spec\.ts$/);
to avoid the special character '.'

Karma error: Can't find variable: angular

I'm trying for a week run karma in a project. I've follow this tutorial AngularJS Unit Test but when run karma start the console shows this error:
PhantomJS 2.1.1 (Linux 0.0.0) ERROR
ReferenceError: Can't find variable: angular
at /home/user/workspace/UnitTest/app/app.js:1
I thought the problem was in my project, so i've created a new one and the error persists.
My karma.conf.js is
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'app/*.js',
'tests/*.js',
'node_modules/angular/angular.js',
'node_modules/angular/angular.min.js',
'node_modules/angular-mocks/angular-mocks.js'
],
exclude: [
],
preprocessors: {
},
reporters: ['progress'],
// web server port
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
customLaunchers: {
Chrome_without_security: {
base: 'PhantomJS',
flags: ['--disable-web-security']
}
},
singleRun: false,
concurrency: Infinity
})
}
and app.js
angular.module('MyApp', [])
.filter('reverse',[function(){
return function(string){
return string.split('').reverse().join('');
}
}])
I've tried to change the node version too, but it isn't worked.
The solution was put the angular imports before the app files like this:
files: [
'node_modules/angular/angular.js',
'node_modules/angular/angular.min.js',
'node_modules/angular-mocks/angular-mocks.js',
'app/*.js',
'tests/*.js'
]

SystemJs and jasmine spyOn error "Module Exports Cannot Be Changed Externally"

I was using webpack+aurelia for a project and recently switch to JSPM version 0.16.52. I use jasmine's spyOn for utility or factory functions that are imported into my classes. However tests that have spyOn(object, 'method') have this error:
"Module Exports Cannot Be Changed Externally"
This occurs when jasmine sets the spied method on the module obj[methodName] = spiedMethod'
Here is a very simple example:
test.js
import * as env from '../../src/env';
describe('stackoverflow example', () => {
it('runs the test', () => {
// this gets thrown and swallowed. jasmine does not report an error, but does not increase the test count.
let envSpy = spyOn(env, 'getBaseUrl');
});
});
env.js
export function getBaseUrl(location) {
return location.port ? `http://${location.hostname}:9001/api/`: '/api/';
}
karam.conf.js
'use strict'
const path = require('path')
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns
basePath: __dirname,
// frameworks to use
frameworks: ['jspm', 'jasmine'],
// list of files / patterns to load in the browser
files: [],
// list of files to exclude
exclude: [],
jspm: {
// Edit this to your needs
loadFiles: [
'test/unit/setup.js',
'test/unit/**/*.js'
],
serveFiles: [
'src/**/*.*',
'jspm_packages/system-polyfills.js'
],
paths: {
'*': 'src/*',
'test/*': 'test/*',
'github:*': 'jspm_packages/github/*',
'npm:*': 'jspm_packages/npm/*'
}
},
// preprocess matching files before serving them to the browser
preprocessors: {
'test/**/*.js': ['babel'],
'src/**/*.js': ['babel']
},
'babelPreprocessor': {
options: {
sourceMap: 'inline',
presets: [ ['es2015', { loose: true }], 'stage-1'],
plugins: [
'syntax-flow',
'transform-decorators-legacy',
'transform-flow-strip-types',
[ 'istanbul', { 'ignore': 'test/' } ]
]
}
},
// test results reporter to use
reporters: ['mocha'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// 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
browsers: ['Chromium'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
setup,js
import 'babel-polyfill'; // for async/await
import 'aurelia-polyfills';
import {initialize} from 'aurelia-pal-browser';
initialize();
UPDATE
When I pulled down a fresh copy of Aurelia-esnext I did not receive the error. So commented out all my tests in my production app and the first spyOn worked, but as i added more tests I started recieving the error again, and it seems to be the way the module is loaded by systemjs. Below is how the imported module object looks when it is loaded into the test
Fresh Copy does not throw
{
__esModule: true,
getBaseUrl: (),
__proto__: Object
}
Original that throws
{
__esModule: (...)
get __esModule: ()
set __esModule: ()
getBaseUrl: (...)
get getBaseUrl: ()
set getBsaeUrl: ()
_proto__: Object
}
Update
I found the snippet of code in system.js where the difference in import occurs. In my larger original project loader.defined[name]; returned undefined and the fresh copy of aurelia loader.defined[name]; is defined...still have not found a workaround
system.src.js
function getModule(name, loader) {
var exports;
var entry = loader.defined[name];
if (!entry) {
exports = loader.get(name);
if (!exports)
throw new Error('Unable to load dependency ' + name + '.');
}
else {
if (entry.declarative)
ensureEvaluated(name, entry, [], loader);
else if (!entry.evaluated)
linkDynamicModule(entry, loader);
exports = entry.module.exports;
}
if ((!entry || entry.declarative) && exports && exports.__useDefault)
return exports['default'];
return exports;
}

ENFILE: File Table Overflow with Karma

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

Grunt, Jasmine, Phantom, React Unit Testing: React throws on ReactElementValidator

I'm using Grunt to run Jasmine unit tests with Phantom.
Grunfile.js
module.exports = function (grunt)
{
"use strict";
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-karma');
grunt.initConfig(
{
pkg: grunt.file.readJSON('package.json'),
browserify: {
dev: {
files: {
'test-output.js':['src/methods.js']
},
options: {
browserifyOptions: {
debug: true
}
}
}
},
karma:
{
unit:{
configFile:"karma.conf.js"
}
}
});
};
with this Karma config file
module.exports = function(config)
{
config.set({
basePath: '',
frameworks: ['browserify', 'jasmine'],
files: [
'myDir/*.js'
],
exclude: [
],
preprocessors: {
'myDir/*.js':['browserify','reactify']
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['PhantomJS'],
browserify: {
debug: true,
transform: []
},
plugins: [
'karma-phantomjs-launcher',
'karma-jasmine','karma-bro'],
singleRun: true
});
};
React is installed locally as a package in the node_modules folder. I can grunt browserify and everything gets bundled into test-ouput.js as expected, but when I do grunt karma I get the error:
TypeError: 'undefined' is not a function (evaluating 'ReactElementValidator.createElement.bind
If I inspect the test-ouput.js file I can see that the ReactElementValidator.createElement.bind function is inside of the bundle. Any ideas what could be causing this?
This a know issue with phantomJS < 2.0. To fix this simply install phantomjs polyfill like this:
npm install --save-dev phantomjs-polyfill
And add it to the config like this.
files: [
'node_modules/phantomjs-polyfill/bind-polyfill.js',
'myDir/*.js'
]
I hope this helped.

Categories