72

I have two javascript files which contain mocha test cases.

//----------abc.js -------------

describe("abc file", function(){
  it("test 1" , function(){
    assert.equal(20 , 20); 
  });
}); 

//---------xyz.js--------------
describe("xyz file", function(){
      it("test 1" , function(){
        assert.equal(10 , 10); 
      });
    });

I have put them in a folder called test and when I execute the mocha command the first file(abc.js) is always executed before xyz.js. I thought this might be due to alphabetical ordering and renamed the files as

abc.js => xyz.js
xyz.js => abc.js

but still, the content of the xyz.js (previously abc.js) is executed first. How can I change the execution order of these test files?

Félix Paradis
  • 5,165
  • 6
  • 40
  • 49
tnishada
  • 1,315
  • 1
  • 16
  • 24

8 Answers8

66

In the second file, require the first one:

--- two.js ---
require("./one")

or if you are using ES modules:

--- two.js ---
import "./one"

Mocha will run the tests in the order the describe calls execute.

Inigo
  • 12,186
  • 5
  • 41
  • 70
Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
  • I like this, much cleaner. Will test this out. Are there any implications of doing it this way (variable scoping between test files ?) – mekdev Aug 24 '15 at 22:50
  • 4
    For those who ask the same question as me: "will the required test be executed twice if it is already matched by the mocha run options?", the answer is "no". So this solution seems much better than executing a random alphabetical order. – Gnucki Aug 04 '16 at 07:52
  • 9
    @Gnucki Alphabetical order is, *by definition*, not random. – Louis Aug 21 '16 at 13:09
  • 12
    Random here refers to the fact that there is no reason that the alphabetical order matches the test order (except if you prefix your filenames which is certainly a bad thing). – Gnucki Aug 21 '16 at 16:19
  • This is very much the best solution, as it allows you to put things in dependency order automatically. The only question I would ask is if there's anything you can do to leverage this to make running your tests dependent on the success of (one or more of?) the tests in the required file (I probably don't need to test pulling data if my login tests failed, for example). – Trevortni Dec 16 '21 at 17:42
  • 1
    @Gnucki What you are referring to is "arbitrary order", not "random order". – Inigo Sep 19 '22 at 17:41
  • This is a most excellent answer. Too bad it's not documented by Mocha. I submitted a request that they do that: https://github.com/mochajs/mocha/issues/4925 – Inigo Sep 19 '22 at 18:28
61

I follow a totally seperate solution for this.

Put all your tests in a folder named test/ and Create a file tests.js in the root directory in the order of execution

--- tests.js ---
require('./test/one.js')
require('./test/two.js')
require('./test/three.js')

And in the tests files one.js, two.js and so on write your simple mocha tests

this way if you want to run them in the order you have defined then just run mocha tests.js

AJB
  • 7,389
  • 14
  • 57
  • 88
35

Mocha has a --sort (short -S) option that sorts test files:

$ mocha --help

[...]
    -S, --sort                              sort test files
[...]
Louis
  • 146,715
  • 28
  • 274
  • 320
  • 15
    In alphabetical order of file name. – Louis Jun 17 '15 at 22:01
  • Thanks, I assumed that but wanted to confirm. – generalchaos Jun 18 '15 at 16:48
  • So if i don't sort them ,could you please tell me in which order the files will be executed? – Medi Jul 09 '18 at 16:09
  • 1
    @Alexander, probably _«directory order»_ so very much dependent on your file system. Under Linux, probably the order in which files were created. On MS-Windows, it's likely random (okay, probably not, but I'm not sure what NFS does at the moment). On Mac OS/X, it will be sorted. The filesystem does that automatically to accelerate the _Finder_. – Alexis Wilke Jan 17 '19 at 17:21
  • 5
    Remember: 1, 11, 2, 3, 4 – Moulde Aug 28 '20 at 14:22
  • I struggled a lot with this, because I had lots of async tests, until I realized I had to put before() and after() INSIDE the top level describe. – Rafael Medeiros Feb 05 '21 at 15:21
  • @tnishada I'm not sure why you accepted this answer as it does not AT ALL answer your question: "How can I change the execution order of these test files?". Either of the higher scoring answers do that. You should change the accepted answer. – Inigo Sep 19 '22 at 17:48
16

Since mocha sorts files in alphabetical order, I usually prefix my test files names with numbers, like:

  • 0 - util.js
  • 1 - something low level.js
  • 2 - something more interesting.js

etc.

In addition to being really easy to maintain (no gulp grunt or any of that nonsense, no editing your package.json...), it provides the benefit that:

  • people reading your source code get an idea of the structure of your program, starting from the less interesting parts and moving up to the business layer
  • when a test fails, you have some indication of causality (if something failed in 1 - something.js but there are no failures in 0 - base.js then it's probably the fault of the layer covered by 1 - something.js

If you're doing real unit tests of course order should not matter, but I'm rarely able to go with unit tests all the way.

djfm
  • 2,317
  • 1
  • 18
  • 34
  • This is the most accurate answer. I ended up doing this. While is not elegant is the best way to ensure certain order of execution, since by default files are tested alphabetically. Thanks djfm!! – Rodrigo Aug 18 '18 at 16:14
  • 1
    The problem with this is that 10 runs before 2. – Matt Aug 19 '20 at 14:55
  • @Matt I believe the author meant giving numbers to 'levels' not to 'steps'. I ended up numbering my steps instead too and facing the same problem now - 10 runs before 2. – yentsun Jan 03 '22 at 05:51
  • 1
    padding with zeroes (like 001-067) helped – yentsun Jan 03 '22 at 05:58
9

If you prefer a particular order, you can list the files (in order) as command-line arguments to mocha, e.g.:

$ mocha test/test-file-1.js test/test-file-2.js

To avoid a lot of typing every time you want to run it, you could turn this into an npm script in your package.json:

{
  // ...
  "scripts": {
    "test": "mocha test/test-file-1.js test/test-file-2.js"
  }
  // ...
}

Then run your suite from the command line:

$ npm test

Or if you're using Gulp, you could create a task in your gulpfile.js:

var gulp = require('gulp');
var mocha = require("gulp-mocha");

gulp.task("test", function() {
  return gulp.src([
      "./test/test-file-1.js",
      "./test/test-file-2.js"
    ])
    .pipe(mocha());
});

Then run $ gulp test.

David Schneider
  • 177
  • 2
  • 3
  • 1
    i'm not sure this is true. i tested this out by passing in 3 files on the command line, and mocha executed them in non-sequential order. – emilebaizel Oct 28 '16 at 20:18
  • It tries to read them all as one file, this didn't work for me. **Warning**: Could not find any test files matching pattern `mocha test1.js test2.js` "No test files found" – mattyb Jun 11 '17 at 17:22
  • Hmm, it may be that the behavior of Mocha has changed. It's also possible I've misunderstood its behavior and this just _happened_ to work for me. – David Schneider May 07 '18 at 22:53
8

The way it worked for my tests to be executed in a specific order was to create a separate test.js file and then added a describe for each mocha test file I'd wanted to execute.

test.js:

describe('test file 1', function() {
  require('./test1.js')
})

describe('test file 2', function() {
  require('./test2.js')
})

Then simply run mocha test.js

1

I am exporting an array with all required files and that is the way I tell mocha the order of execution through index.js file in the folder with all my test files:

const Login = require('../login');
const ChangeBudgetUnit = require('./changeBudgetUnit');
const AddItemsInCart = require('./addItemsInCart'); 

// if the order matters should export array, not object
module.exports = [
    Login,
    ChangeBudgetUnit,
    AddItemsInCart
];
Troglo
  • 1,497
  • 17
  • 18
1

mocha-steps allows you to write tests that run in a specific sequence, aborting the run at the first failure. It provides a drop-in replacement for it, called steps.

Example usage:

describe('my smoke test', async () => {
  step('login', async () => {})
  step('buy an item', async () => throw new Error('failed'))
  step('check my balance', async () => {})
  xstep('temporarily ignored', async () => {})
})

The repo hasn't seen much activity in three years, but it works fine with Mocha 9.

aalaap
  • 4,145
  • 5
  • 52
  • 59
  • How come this isn't the standard behaviour? I'm plunging into tests for the first time, and parallel execution of insertNewUser, getUserById, updateExistingUser, and deleteExistingUser is a complete non start. – Wayne Smallman Dec 22 '22 at 17:49
  • 1
    @WayneSmallman Generally, tests should not be sequential or depend on other tests, because this makes them NOT "unit" tests. The correct approach to test for eg. `updateExistingUser` is to use a setup routine to add the user (directly to the db - not via the `insertNewUser` function, then testing the update function and finally deleting that user (again, directly from the db). – aalaap Mar 06 '23 at 17:19