Markus Oberlehner

Speeding up Nightwatch.js Powered Acceptance Tests


In my last article series on automated testing, we explored how to set up Nightwatch.js, write smart step definitions, and how to run automated cross-browser acceptance tests on BrowserStack with Nightwatch.js. Today we examine two ways how we can speed up the testing process with Nightwatch.js – because faster is always better.

Running Nightwatch.js without Selenium

We can achieve the first small speed improvement by eliminating Selenium from the setup. As far as I know, the following approach of running tests in Nightwatch.js without Selenium, for now, is only possible with Google Chrome. If you want to run tests in Browsers other than Google Chrome, you still have to rely on Selenium, or you can use BrowserStack, which also doesn’t require you to have Selenium installed locally.

To run tests in Google Chrome directly without using Selenium, you have to change your Nightwatch.js configuration.

module.exports = {
  // ...
  selenium: {
    start_process: false,
  },
  test_settings: {
    default: {
      // ChromeDriver default port.
      selenium_port: 9515,
      selenium_host: "localhost",
      // Clear the default Selenium path prefix.
      default_path_prefix: "",
      desiredCapabilities: {
        browserName: "chrome",
        acceptSslCerts: true,
      },
    },
  },
  // ...
};

Next you have to create a new global script (or add to an already existing one) to start the ChromeDriver in a before and to stop the ChromeDriver in an after hook.

// globals.js
const chromedriver = require("chromedriver");

module.exports = {
  before: (done) => {
    chromedriver.start();
    done();
  },
  after: (done) => {
    chromedriver.stop();
    done();
  },
};

To load the globals file above, you can add the following line to your Nightwatch.js configuration file.

module.exports = {
  // ...
  globals_path: `path/to/your/globals.js`,
  // ...
};

Thats it! After amending your configuration and adding the hooks to start and stop the ChromeDriver, you’re ready to run your tests without having to rely on Selenium. Although the gains in speed are not huge, depending on your setup, you’ll save a few seconds here and there.

Parallelization with test workers

By default, Nightwatch.js runs your tests sequentially, but most modern computers are multi core machines and are able to run multiple processes in parallel. Luckily Nightwatch.js supports running your tests in parallel with so-called test workers. To enable test workers, you have to add the following line to your configuration file.

module.exports = {
  // ...
  test_workers: true,
  // ...
};

By default, Nightwatch.js will use all available CPU cores – if you have 2 cores, it will run 2 tests in parallel, if you have 4 cores it will run 4 tests in parallel, and so on.

If you want to limit the number of cores which Nightwatch.js is allowed to use, you can specify a fixed number.

module.exports = {
  // ...
  test_workers: {
    enabled: true,
    workers: 3,
  },
  // ...
};

In the example above we’re utilizing 3 cores for running tests. But be careful: if you’re sharing your configuration in a Git repository with other users, there might be people with less powerful machines and less cores.

You might notice, that the output is slightly obscured when running tests in parallel. But there is a setting to improve readability of the output with test workers enabled.

module.exports = {
  // ...
  test_workers: true,
  detailed_output: false,
  // ...
};

Conclusion

In a world of TDD, there is nothing as annoying as having to wait for your tests to finish.

Eliminating Selenium from your test setup can improve the speed of your tests slightly. Enabling parallelization with test workers takes it a step further by speeding up your tests by a factor equal to the number of cores you have in your machine (at least theoretically speaking).

Happy testing!