Mocha tests don't run with Webpack and mocha-loader

user3773571 picture user3773571 · Sep 3, 2015 · Viewed 17k times · Source

Background

I am porting some npm scripts to Webpack loaders to better learn how Webpack works and I’ve got everything working except for my Mocha tests: I have one failing test, but it is not showing that Mocha is being run with the mocha-loader or that the test is failing:

enter image description here

Question

What do I need to do differently to get all src/**/*.test.js files to run with with Mocha in Webpack?

Steps to reproduce

  1. Clone https://github.com/trevordmiller/webpack-loaders-playground
  2. Run npm test to see how tests should work
  3. Run npm run dev to see how tests don't run with Webpack

Answer

Jim Skerritt picture Jim Skerritt · Sep 4, 2015

Mocha loader won't run tests while building, it's used to create a bundle specifically containing your tests which you can then run from your browser.

I would recommend creating a separate webpack config file for your tests, which you can then host on a webpack-dev-server that uses a different port from your application. Here's an example that's more-or-less the pattern that I use for my own projects (as of writing this answer):

webpack.tests.config.js

module.exports = {
    entry: 'mocha!./tests/index.js',
    output: {
        filename: 'test.build.js',
        path: 'tests/',
        publicPath: 'http://' + hostname + ':' + port + '/tests'
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                loaders: ['babel-loader']
            },
            {
                test: /(\.css|\.less)$/,
                loader: 'null-loader',
                exclude: [
                    /build/
                ]
            },
            {
                test: /(\.jpg|\.jpeg|\.png|\.gif)$/,
                loader: 'null-loader'
            }
        ]
    },
    devServer: {
        host: hostname,
        port: port
    }
};

tests/index.js

// This will search for files ending in .test.js and require them
// so that they are added to the webpack bundle
var context = require.context('.', true, /.+\.test\.js?$/);
context.keys().forEach(context);
module.exports = context;

package.json

"scripts": {
    "test": "find ./ -name '*.test.js' | xargs mocha -R min -r babel/register",
    "devtest": "webpack-dev-server --config webpack.tests.config.js",
    "dev": "webpack-dev-server --config webpack.config.js"
}

test.html

<!DOCTYPE html>
<html>
    <head>
        <title>Mocha</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="./node_modules/mocha/mocha.css" />
        <script src="/tests/test.build.js"></script>
    </head>
    <body>
    </body>
</html>

Then run npm run devtest, open http://localhost:<port you picked>/webpack-dev-server/test.html, and mocha should run your tests.

If you don't require CSS/LESS or images through your modules, you can remove those loaders from webpack.tests.config.js.

With hot loading enabled this is a really great setup because I can have both my application and my tests running in different browser tabs, then update my code and see my changes and my tests re-running immediately.

You can also run npm run test to execute the same tests through the command line.

Hope this helps.