Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocha isn't displaying any details for failed tests

I'm migrating an app from Sails.js v0.12 to v1.0, which includes upgrading mocha from ^3.5.0 to ^5.2.0. I assume that is the root of the issue, but I can't seem to find a fix.

Before, when a test failed, there would be a summary of the error at the end of the mocha reporter output: the specific assertion that failed, file name, line number, error message, etc. Now, the reporter is coloring the it block in red, but no additional details are show.

I've tried changing the reporter in mocha.opts, which works for the actual execution output, but nothing is enabling the summary at the end. What am I missing?

// ./test/integration/models/User.test.js

describe('User', () => {

  describe('find()', () => {
    it('should return an array of users', () => {
      return User.find()
      .then((users) => {

        users.should.be.a('array');
        true.should.be.false;  // No problems if this is removed

      });
    });
  });

});

In the console:

> node ./node_modules/mocha/bin/mocha test/lifecycle.test.js test/integration/**/*.test.js


√ OtherModel method() should do something: 17ms
1) User find() should return an array of users
'Done.'
PS C:\repos\myproject>
like image 848
carpiediem Avatar asked Oct 19 '25 02:10

carpiediem


2 Answers

Turns out that Mocha is fine and my test definitions are fine, I had simply fixed a totally different migration issue incorrectly. Since version 4, mocha will no longer automatically kill itself when it thinks all tests are complete. This means that one of these two options must be used:

  1. Add --exit to mocha.opts or to wherever the command is called
  2. Run process.exit() in your test suite's JavaScript

I tried the second option by adding process.exit() to the after() block in my test bootstrap file. This is a bad idea and resulted in the confusing behavior above.

To solve my issue, I removed my changes to the after() block and added --exit to mocha.opts. Thanks to Dhruv Choudhary for pointing me in the right direction.

like image 191
carpiediem Avatar answered Oct 21 '25 15:10

carpiediem


you can use done callback. The first strategy suggested in the mocha documentation is using the ‘done’ callback. This is an extra argument to the callback in the it . You call it after the last assertion in your test.

I have seen many people using done() method in wrong way. for example, look at below code,

describe('User', () => {

  describe('find()', () => {
    it('should return an array of users', (done) => {
      return User.find()
      .then((users) => {

        users.should.be.a('array');
        true.should.be.false;  // No problems if this is removed
        done();

      });
    });
  });

});

The above test will work fine and show the test passing, But calling done() in the same then callback is a bad idea because The above code works well until your expectation fails, you might get error like enter image description here

The above failure is not very useful . If we want to utilize the mocha’s error we shouldn’t call done() from the same then() callback. See the below test

describe('User', () => {

    describe('find()', () => {
        it('should return an array of users', (done) => {
            return User.find()
                .then((users) => {

                    users.should.be.a('array');
                    true.should.be.false;
                })
                .then(() => done(), done)
                .catch((error) => {
                    done(error);

                });
        });
    });
});

do not forget to wrap your error with catch block. Now see the difference in the mocha’s failure message with actual and expected..

like image 30
Dhruv Choudhary Avatar answered Oct 21 '25 15:10

Dhruv Choudhary



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!