Explain Codes LogoExplain Codes Logo

Change default timeout for mocha

javascript
mocha
testing
timeout
Alex KataevbyAlex Kataev·Feb 1, 2025
TLDR
mocha.timeout(10000); // Set 10-second timeout globally

Calling mocha.timeout(10000) lets you set a 10-second timeout across all Mocha tests. It's as simple as it gets.

Global timeout settings in configuration

Establish global defaults in mocha.opts

You can set a global default timeout in the mocha.opts file:

--timeout 5000

Or declare it directly within your package.json for easy npm test execution:

"mocha": { "timeout": 5000 }

The beauty of mocha.opts

Using mocha.opts streamlines your Mocha configuration by consolidating settings in one place, promoting consistency and reducing duplication. That's cleaning up like a pro.

Track changes with package.json

By configuring in package.json, it becomes easier to track changes over time using version control system, keeping a historical record of configuration adjustments and ensuring everyone is on the same testing page.

Setting timeout within test files

Describe-level timeout

For permissions on a per-file basis, use this.timeout() in an upper-level describe() function:

describe('Long Running Tests', function() { this.timeout(5000); // No rush, take an extra 5 secs! });

The pitfall of arrow functions

When using this.timeout(), stay away from arrow functions. They have no idea about the Mocha context (this):

// "Who's this?" - Arrow functions, probably 🏹 describe('Example', () => { this.timeout(5000); // 'this' is not the Mocha context here! }); // Good ol' regular function ⏰ describe('Example', function() { this.timeout(5000); // 'this' is the Mocha context! });

Scope and this in Mocha

Keep in mind, with Mocha's context, arrow functions could lead to surprises if you aren't fully aware of how scope and this work.

Timeouts in older environments

If your testing landscape is set in older or legacy browsers, use the mocha.setup() method to set timeouts:

mocha.setup({ timeout: 5000 }); // Flashback to the good old times

Considerations when setting timeouts

Consistency in test behavior

A global default timeout ensures consistent behavior across tests and can help identify sluggish tests, which might indicate a need for a redesign.

Flexibility with default and override

Using both a global default with per-file or per-test overrides provides the flexibility needed for special cases without convoluting your tests. Now, that's having cake and eating it too.

In-depth considerations

Async and timeouts

For asynchronous code, it's wise to set a proper timeout accommodating external factors like network latency and service responses. After all, not everyone is as fast as Flash.

Timeouts within setup and teardown

Hooks like beforeEach() or afterEach() can also have specialized timeouts. Keep this in mind when setup or teardown involves async operations.

beforeEach(function(done) { this.timeout(10000); // We got all day for setup // ... setup code ... });

CI environments and timeouts

Sometimes, due to varying performance characters in CI environments, timeouts may need an expansion:

"scripts": { "test-ci": "mocha --timeout 10000" }

Common issues and rare cures

Fixing flaky tests

Timeouts can be the magic wand that solves flaky tests that fail due to intermittent delays. Who knew adding time could solve so many problems?

Environment-specific timeouts

In scenarios where different timeouts are needed across different environments (development, staging, production), consider using environment variables:

const defaultTimeout = process.env.MOCHA_TIMEOUT || 5000; mocha.timeout(defaultTimeout); // One size doesn't always fit all