64

I am trying to run karma tests from gulp task and I am getting this error:

Error: 1
   at formatError (C:\Users\Tim\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:161:10)
   at Gulp.<anonymous> (C:\Users\Tim\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:187:15)
   at Gulp.emit (events.js:95:17)
   at Gulp.Orchestrator._emitTaskDone (C:\path\to\project\node_modules\gulp\node_modules\orchestrator\index.js:264:8)
   at C:\path\to\project\node_modules\gulp\node_modules\orchestrator\index.js:275:23
   at finish (C:\path\to\project\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:21:8)
   at cb (C:\path\to\project\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:29:3)
   at removeAllListeners (C:\path\to\project\node_modules\karma\lib\server.js:216:7)
   at Server.<anonymous> (C:\path\to\project\node_modules\karma\lib\server.js:227:9)
   at Server.g (events.js:180:16)

My system is Windows 7, nodejs version is v0.10.32, gulp version:

[10:26:52] CLI version 3.8.8
[10:26:52] Local version 3.8.9

Also, the same error I am getting on Ubuntu 12.04 LTS while on newer Ubuntu (not sure what version) and mac os it is seems to be working ok. What can cause this error?

Update 5/11/2016: Before writing comment about the fact that accepted answer hide errors, please, see first two comments to that particular accepted answer. Use it only if know what you are doing. Related info: https://github.com/karma-runner/gulp-karma/pull/15

Timur
  • 6,668
  • 1
  • 28
  • 37

10 Answers10

131

How are you running your tests with Gulp? I came up against this issue recently on OSX, running node v0.11.14 and gulp 3.8.10, whenever there were failing tests.

Changing from the recommended:

gulp.task('test', function(done) {
    karma.start({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }, done);
});

To:

gulp.task('test', function(done) {
    karma.start({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }, function() {
        done();
    });
});

...got rid of this error.

Seems to be down to how gulp handles error messages when an error is signalled in a callback. See Improve error messages on exit for more information.

McDamon
  • 1,506
  • 1
  • 9
  • 3
  • 2
    Interesting solution. So this seems to be not an issue but incorrect error handling and processing in gulp. Your solution has one drawback: gulp will not report any error by itself and you will have to look into logs if one happens. But for me it is acceptable. Thank you – Timur Nov 17 '14 at 02:41
  • 3
    Thanks, though as per the link, you can do something like `function(exitStatus) { done(exitStatus ? "There are failing unit tests" : undefined); }` to pass the error back to Gulp - I didn't as the Karma reporting mechanism was working fine for me. – McDamon Nov 17 '14 at 08:06
  • You have saved me a lot of headeaches, my friend – ŁukaszBachman Dec 09 '14 at 10:45
  • Is there a way to make it run with `singleRun: false` ? – inf3rno Oct 17 '15 at 22:36
  • Solved my problem. Thanks a bunch! – Munim Nov 02 '15 at 05:48
  • 6
    I seriously don't know how this solves any issue... AT ALL. First of all, the `done` callback needs an exit status. If choose not to provide one (as a fix for an unknown issue), your test task has no sense: your **tests can fail**, but your gulp task will not exit, it will run other tasks **as if your tests have passed**. My point is that even if this is a *solution*, it doesn't solve any problem at all! A better solution would be to disable tests :) – gion_13 Nov 03 '15 at 15:16
  • 18
    This is very incorrect and misleading answer: doing this change means that in case of error gulp won't exit with proper exit code but rather will exit with 0, signaling correct exit code for a failed process. This can break things on a CI server, chaining of commands etc. DON'T do this. – pkozlowski.opensource Nov 06 '15 at 21:24
  • please take a look at this issue https://github.com/karma-runner/gulp-karma/pull/15 – Vasiliy Yorkin Nov 09 '15 at 12:30
  • @VasiliyYorkin Thanks, added it to question as update. – Timur May 12 '16 at 03:35
  • 2
    See: https://github.com/ONE-LOGIC/gulp-modular-karma/commit/62c5df66b50e76de6b3f97a4794c3f574949344c for working solution that doesn't break the exit code – Avindra Goolcharan Jul 09 '16 at 14:03
  • This is so strange why and how it worked??? do you need more question?? ma?rks??? – bitten Aug 19 '16 at 21:36
  • @AvindraGoolcharan that's not a good solution, as the callback isn't passed to karma, but executed right away. You're basically doing this: `new KarmaServer({..},undefined).start(); done();` – hugo der hungrige Oct 07 '16 at 16:41
9

None of these solutions worked correctly for me using gulp 3.9.1 and karma 1.1.1. Adding a reference to gulp-util npm install --save-dev gulp-util and updating the task to the below fix the error output very nicely, while maintaining exit status correctly.

var gutil = require('gulp-util');

gulp.task('test', function (done) {
  new Server({
    configFile: __dirname + '/karma.conf.js',
    singleRun: true
  }, function(err){
        if(err === 0){
            done();
        } else {
            done(new gutil.PluginError('karma', {
                message: 'Karma Tests failed'
            }));
        }
    }).start();
});
brocksamson
  • 812
  • 1
  • 9
  • 17
  • Best solution for me although it has an additional dependency. However, it fails the run if tests fail and has no stack trace in the end. – Marc Scheib Feb 12 '17 at 11:57
5

Below is a code snippet from gulp patterns on using Karma. It's a bit similar, but also uses the newer method how to start the karma.

/**
 * Start the tests using karma.
 * @param  {boolean} singleRun - True means run once and end (CI), or keep running (dev)
 * @param  {Function} done - Callback to fire when karma is done
 * @return {undefined}
 */
function startTests(singleRun, done) {
    var child;
    var excludeFiles = [];
    var fork = require('child_process').fork;
    var KarmaServer = require('karma').Server;
    var serverSpecs = config.serverIntegrationSpecs;

    if (args.startServers) {
        log('Starting servers');
        var savedEnv = process.env;
        savedEnv.NODE_ENV = 'dev';
        savedEnv.PORT = 8888;
        child = fork(config.nodeServer);
    } else {
        if (serverSpecs && serverSpecs.length) {
            excludeFiles = serverSpecs;
        }
    }

    var server = new KarmaServer({
        configFile: __dirname + '/karma.conf.js',
        exclude: excludeFiles,
        singleRun: singleRun
    }, karmaCompleted);
    server.start();

    ////////////////

    function karmaCompleted(karmaResult) {
        log('Karma completed');
        if (child) {
            log('shutting down the child process');
            child.kill();
        }
        if (karmaResult === 1) {
            done('karma: tests failed with code ' + karmaResult);
        } else {
            done();
        }
    }
}
Igor Lino
  • 532
  • 7
  • 10
5

What worked for me and gave a nice formatted error message is to provide an Error instance to the done callback.

gulp.task('test', function(done) {
    karma.start({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }, function(result) {
        if (result > 0) {
            return done(new Error(`Karma exited with status code ${result}`));
        }

        done();
    });
});
Andi Giga
  • 3,744
  • 9
  • 38
  • 68
VuesomeDev
  • 4,095
  • 2
  • 34
  • 44
  • This one still creates a StackTrace for me although it is shorter. And this one has no additional deps (see gulp-util solution which however creates no stacktrace). – Marc Scheib Feb 12 '17 at 11:56
2

If you want to return with an error code, and want to see Karma's error output but not Gulp's (probably unrelated) stack trace:

gulp.task('test', function() {
    karma.start({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }, function(karmaExitStatus) {
           if (karmaExitStatus) {
               process.exit(1);
           }
    });
});
1

Not sure about Ubuntu, but I was getting a similar error on Windows, and installing one version back fixed it right away like this:

npm install -g gulp@3.8.8
npm install gulp@3.8.8
J0e3gan
  • 8,740
  • 10
  • 53
  • 80
onfilm
  • 11
  • 2
1

this is gulp's way of telling your tests have failed and that karma exited with a return code of 1. Why you would want to call done yourself and not pass the error as a message baffles me.

Laurent Picquet
  • 1,147
  • 11
  • 12
0

The right way to solve this according to Karma's documentation and https://github.com/pkozlowski-opensource, is to rely on Karma's watch mechanism rather than Gulp's:

gulp.task('tdd', function (done) {
  karma.start({
    configFile: __dirname + '/karma.conf.js'
  }, done);
});

Note the omission of singleRun: true.

@McDamon's workaround will work for gulp.watch, but you don't want to swallow exit codes like that when running on a CI server.

Gulp is also reworking how they handle exit codes in scenarios just like this one. See https://github.com/gulpjs/gulp/issues/71 and the other dozen or so related issues.

Seth
  • 6,514
  • 5
  • 49
  • 58
0
gulp.task('test', function(done) {
    karma.start({
        configFile: __dirname + '/karma.conf.js',
        singleRun: false 
    }, done);
});

passing singleRun: false argument will prevent the process from returning a value different of 0 (which would signify an error and exit gulp).

Run with singleRun: true if you only launching your test from a command line, not part of a continuous integration suite.

deBrice
  • 485
  • 1
  • 5
  • 11
0

In case anyone else comes here, do not use the accepted solution. It will hide failed tests. If you need a quick solution to modify your gulp test task, you can use the solution found in this comment in this github thread.

gulp.src(src)
    // pipeline...
    .on('error', function (error) {
        console.error('' + error);
    });