Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gulp-Mocha fails to exit, but Mocha does #54

Closed
drundle opened this issue Aug 29, 2014 · 53 comments · Fixed by #73
Closed

Gulp-Mocha fails to exit, but Mocha does #54

drundle opened this issue Aug 29, 2014 · 53 comments · Fixed by #73

Comments

@drundle
Copy link

drundle commented Aug 29, 2014

Hi,

I am running a simple test (its failing, but that a separate issue).

Using:

"gulp-mocha": "^1.0.0",

When I run this using Gulp-Mocha (it happens on Travis as well), it does not exit the testing execution, but when I run this using Mocha, it fails, and exits back to the command prompt.

var assert = require("assert"),
    elasticsearch = require('elasticsearch'),
    client;

    client = new elasticsearch.Client();

    describe(' people', function(){

    beforeEach(function(done){

        //in Gulp Mocha this stops the test runner exiting
        //that this does not work is not this issue.
        client.deleteByQuery({
            index: 'people',
            q: '*'
        }, function (error, response) {
            done();
        });


       //If i just do done(), it will exit. in both.
       //done();

    });

    describe('add a entry into the index', function(){
        it('should add Dave as a person to the database', function(done){
            assert.equal(1,1);
        });
    });
});
@ilanbiala
Copy link

+1, the task never finishes...it has to be ctrl+c'ed.

@rymai
Copy link

rymai commented Sep 8, 2014

I'm experiencing this as well. I'm using gulp-mocha@1.0.0.

@floatdrop
Copy link
Contributor

You did not call done in it callback. Shouldn't it be like this:

    describe('add a entry into the index', function(){
        it('should add Dave as a person to the database', function(done){
            assert.equal(1,1);
            done();
        });
    });

Or like this:

    describe('add a entry into the index', function(){
        it('should add Dave as a person to the database', function(){
            assert.equal(1,1);
        });
    });

@davejlong
Copy link

I'm having the same problem. Checked through my tests and none of them have an uncalled done callback.

Also if it was an issue of done not being called, then a timeout error would arise.

@floatdrop
Copy link
Contributor

@davejlong gist with hanging test and gulp file would be nice.

@floatdrop
Copy link
Contributor

@drundle second guess, that you should close client in afterEach method. I will look into as soon as possible.

@davejlong
Copy link

@floatdrop It's not a hanging test. When I run gulp, it outputs that the task finishes, but then gulp doesn't exit.

@floatdrop
Copy link
Contributor

@davejlong it can be caused by hanging sockets or setIntervals - elastic/elasticsearch-js#40

Could you share your gulpfile and test that causing gulp to hang?

@davejlong
Copy link

Ahh I found it. There was a setTimeout in my code that was being tested that caused the tests to hang.

@ilanbiala
Copy link

@davejlong @floatdrop it's still an issue in general. My tests exit when running mocha, but they don't exit when running mocha through gulp-mocha.

@sindresorhus do you have any idea what's happening with this?

UPDATE:

1.1.0 doesn't fix this by the way.

@floatdrop
Copy link
Contributor

@ilanbiala could you post a gulp task, that we can reproduce bug?

@ilanbiala
Copy link

gulp.task('mocha', function() {
    return gulp.src([
        'app/tests/init.test.js',
        'app/tests/*.test.js'
    ], { read: false })
        .pipe(mocha({
            reporter: 'spec',
            globals: {
                should: require('should')
            }
        }));
});

[10:28:34] Finished 'mocha' after 16 s, doesn't exit though.

@floatdrop
Copy link
Contributor

@ilanbiala this code is working for me and gulp is exiting fine. Can you replace 'app/tests/init.test.js', 'app/tests/*.test.js' with only one test. For example app/tests/init.test.js?

@ilanbiala
Copy link

Doesn't work for me if I put in only one test.

However, if the tests fail, then gulp-mocha properly exits.

@floatdrop
Copy link
Contributor

@ilanbiala good. It means, that init.test.js is potential cause of hanging node. Could you post it as gist?

@ilanbiala
Copy link

That file is used to start up the server and connect to the test database. Is there a good way to have my server and database running prior to running the tests?

@floatdrop
Copy link
Contributor

@ilanbiala start server before tests and tear it down after - I think that what before and after hooks are for. Make sure, that you close server after tests are run - other wise node will hang (same way, as if you write http.createServer and leave it listen to connections).

@ilanbiala
Copy link

The server is started just by requiring or running the file. What can I do to kill the server after all the tests have finished?

@floatdrop
Copy link
Contributor

@ilanbiala either you call close method on server object (if it provides one), or call process.exit(0) to force terminate the run.

@ilanbiala
Copy link

var requireUtils = require('../utils/require');

/**
 * Start the server so Mocha's tests can access database, etc.
 */

var server;

describe('Server tests:', function() {

  it('should be able to start without problems', function(done) {
    server = require('../../server');

    var testFiles = requireUtils.getGlobbedFiles([
        'app/tests/*.test.js'
      ], 'app/tests/');

    testFiles.forEach(function(testFile) {
      if (testFile !== 'init.test.js') {
        require('./' + testFile);
      }
    });

    server.process.close(function() {
      console.log('finished tests');
      done();
    });
  });

});

Right now I'm trying to set it up that way, but it seems that the console.log happens before the tests in the required files are run. Any thoughts on a good way to set this up..? I'm pretty lost.

@floatdrop
Copy link
Contributor

@ilanbiala it is pretty hard to help without knowing, what inside utils/require and server. Also I don't quite understand, why you do require in testFiles.forEach - don't you add those tests in gulpfile? And many other questions.

In your place I'd rather running new server for bunch of tests instead of sharing one server for all kind of tests (it is good practice to run test on fresh prepared server/database).

I created example repository to demonstrate work with server - https://github.com/floatdrop/gulp-mocha-example (it exits after running all tests successfully).

@ilanbiala
Copy link

utils/require is a function that wraps glob and allows me to pass in an array of files to be required and resolved. server is the server, and it automatically runs on require. I'll try to figure something out based on your example and what is set up. Thanks!

@britztopher
Copy link

Are any of you guys using loopback at all? Im having the same issue with the above referenced ticket, and I think they are related to your issues as well even if you are not using loopback, as i think its something conceptually wrong with node applications.

@drundle
Copy link
Author

drundle commented Sep 18, 2014

@floatdrop, yes we called done() on in (I forgot to put in the example, applogies)

The issue is I can run identical code in both Mocha directly and via gulp-mocha, but get different behaviour

@floatdrop
Copy link
Contributor

@drundle yeah, that's bummer. It should be resolved by #20.

@solshark
Copy link

Same issue in about same environment. Never get exited from gulp.

  it 'should respond with JSON array', (done) ->
    data.save ->
      request app
        .get '/api/data'
        .expect 200
        .expect 'Content-Type', /json/
        .end (err, res) ->
          return done err if err
          res.body.should.be.instanceof Array
          res.body.should.have.length 1
          done()

@jkarttunen
Copy link

Had same issue. The cause was a mongoose connection that was opened but not properly caused on tests. Adding

    after(function(){
      mongoose.connection.close()
    })

fixed this for me.

@gaastonsr
Copy link

Saw this trick in another issue.

gulp.task('default', function () {
  return gulp.src('test/**/*_test.js')
    .pipe(mocha())
    .once('end', function () {
      process.exit();
    });
});

@juanpabloaj
Copy link

+1

@juanpabloaj
Copy link

@futurechan I have the same problem and I close the db connections with

after(function(){
  mongoose.connection.close()
})

I use node 0.10.33, some have the problem with node 0.11.0 ?

In a supertest issue , I read this

Try 0.11.0, it has fixed this problem. If you still see an issue, it's going to be a problem with the gulp task.

@morenoh149
Copy link
Contributor

+1 same issue. So what's the consensus? should gulp-mocha terminate these connections or is it the responsibility of the developer? If the latter then gulp-mocha has the responsibility of mentioning it in the docs @sindresorhus

@gaastonsr
Copy link

Developer responsibility. Maybe a note on the docs could help...

@morenoh149
Copy link
Contributor

Sovled by #73

@juanpabloaj
Copy link

If, I use process.exit() this kill the gulp.watch .

I try with this test code (without database connections) :

https://gist.github.com/juanpabloaj/f1ea60417f47897c940f

describe('app test', function(){
  it('app return json message', function(done){
    request(app)
      .get('/')
      .expect(200)
      .end(function(err, res){
        res.body.message.should.match(/test/);
        done();
      });
  });
});

when I use mocha -w test_app.js, work fine

$ mocha -w test_app.js

  app test
    ✓ app return json message

  1 passing (49ms)

  app test
    ✓ app return json message

  1 passing (13ms)

but, If I use gulp, only the first time work fine

$ gulp
[13:04:22] Using gulpfile ~/code/nodejs/gupl-mocha/fail_to_exit/gulpfile.js
[13:04:22] Starting 'watch'...
[13:04:22] Finished 'watch' after 8.98 ms
[13:04:22] Starting 'default'...
[13:04:22] Finished 'default' after 8.52 μs
[13:04:25] Starting 'tests'...


  app test
    ✓ app return json message


  1 passing (23ms)

[13:04:26] Finished 'tests' after 358 ms
[13:04:28] Starting 'tests'...


[13:04:28] 'tests' errored after 154 ms
[13:04:28] Error in plugin 'gulp-mocha'
Message:
    listen EADDRINUSE
Details:
    code: EADDRINUSE
    errno: EADDRINUSE
    syscall: listen
    domainEmitter: [object Object]
    domain: [object Object]
    domainThrown: false
Stack:
Error: listen EADDRINUSE
    at errnoException (net.js:904:11)
    at Server._listen2 (net.js:1042:14)
    at listen (net.js:1064:10)
    at Server.listen (net.js:1138:5)
    at EventEmitter.app.listen (/Users/pablo/code/nodejs/gupl-mocha/fail_to_exit/node_modules/express/lib/application.js:559:24)
    at Object.<anonymous> (/Users/pablo/code/nodejs/gupl-mocha/fail_to_exit/server.js:15:5)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
  app test
    ✓ app return json message


  1 passing (13ms)

@morenoh149
Copy link
Contributor

@juanpabloaj I'm no expert on testing. But it sounds like you could recreate the mocha object for every test. This would also help isolate issues. Could you try that?

@felipe-pereira
Copy link

In my case I create a child process on server.js (a simple scheduler), added process.exit() as suggested, but it was useless since on-error or on-end are never called.

@AndrewSouthpaw
Copy link

I tried the mongoose.connection.close() option, but gulp mocha would still hang.

The problem with process.exit() for me is that I can't reach any tasks in a sequence following mocha. This is problematic when I want to, say, run coveralls afterwards. Has anyone found a different workaround?

@gaastonsr
Copy link

How do you run your tests? You might do something like

gulp test; coveralls

@AndrewSouthpaw
Copy link

Hmm, that's an interesting idea. Ultimately, I'm using Coveralls for Travis, so I placed an extra command in the .travis.yml:

after_script:
 - ./node_modules/.bin/gulp coveralls

That did the trick alright.

Still, something doesn't seem right with me about needing a workaround like that. I wish I could figure out the root problem.

Oizor added a commit to boris-arkenaar/javascript-examiner that referenced this issue Apr 9, 2015
@richardschneider
Copy link

Using gulp-spawn-mocha fixes the problem for me.

@brandon-collins
Copy link

I was having a similar issue, i.e. my test run and all pass, all done callback called but mocha was not exiting as I'd expect it to. The solution was that I had an unexpected option defined in my global mocha.opts file.

--no-exit

removing the above solved my issue.

@justinr1234
Copy link

Fixed for me: https://github.com/dreame4/gulp-exit

@suplo
Copy link

suplo commented Apr 13, 2016

@juanpabloaj I have the same problem as you with asynchronous tests (in my case I used request to test a Rest API). By rewriting the test as

  var check = function(done, f) {
    try {
      f();
      done();
    } catch (e) {
      done(e);
    }
  };

  it('should validate', (done) => {
    check(done, () => {
      request.post(url, { form: data }, (err, response, body) => {
         // do some assertions
      });
    });
  });

the test passed for both single-run and gulp-mocha (watching mode)

Ref https://stackoverflow.com/questions/11235815/is-there-a-way-to-get-chai-working-with-asynchronous-mocha-tests?answertab=active#tab-top

@Wtower
Copy link

Wtower commented Aug 15, 2016

This issue still persists. Valid workarounds are gulp-spawn-mocha by @richardschneider and gulp-exit by @justinr1234.

Unfortunately, neither works well with istanbul.

@Wtower
Copy link

Wtower commented Aug 18, 2016

Based on the comment in this same issue this is my mocha task:

  mocha: function () {
    gulp.doneCallback = function (err) {
      process.exit(err ? 1 : 0);
    };
    return gulp.src(paths.mocha)
      .pipe(plumber())
      .pipe(mocha({reporter: 'spec', colors: true}))
      .on('error', handleError('Mocha'))
      .pipe(istanbul.writeReports());
  },

snoe pushed a commit to snoe/node-host that referenced this issue Oct 3, 2016
snoe pushed a commit to snoe/node-host that referenced this issue Oct 3, 2016
Add build status to README

gulp test hangs - sindresorhus/gulp-mocha#54
snoe pushed a commit to snoe/node-host that referenced this issue Oct 3, 2016
Add build status to README

gulp test hangs - sindresorhus/gulp-mocha#54
nhynes pushed a commit to snoe/node-host that referenced this issue Oct 4, 2016
Add build status to README

gulp test hangs - sindresorhus/gulp-mocha#54
nhynes pushed a commit to neovim/node-host that referenced this issue Oct 4, 2016
Add build status to README

gulp test hangs - sindresorhus/gulp-mocha#54
@dbellavista
Copy link

dbellavista commented Oct 23, 2016

Personally I need mongoose to connect on begin and disconnect when all tests are finished. So in every test I require:

require('./test-setup');
// test-setup.js
const chai = require('chai');
/* setup chai */
const mongoose = require('mongoose');
before(done => mongoose.connect('<mongo-connection-string>', done));
after(done => mongoose.disconnect(done));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.