Monthly Archives: February 2015

QUnit anti-patterns

I’d like to challenge the assert.ok and assert.not* methods. I think they’re a bad practice.

assert.ok

Using assert.ok() indicates one of two problems:

  • The software (or testing strategy) is unreliable. (Unsure what value to expect.)
  • The author is lazy and uses it as shortcut for a proper comparison.

The former necessitates improvement in the code being tested. The latter comes with two additional caveats:

  1. Less debug information. (No actual/expected diff). Without an expected value provided, one can’t determine what’s wrong with the value.
  2. Masking regressions. Even if the API being tested returns a proper boolean and `ok` is just a shortcut, the day the API breaks (e.g. returns a number, string, array, function, Promise or other object) the test will not catch it.

Common examples:

// Meh
assert.ok( bool );
assert.ok( fn );

// Better?
assert.strictEqual( bool, true );
assert.equal( typeof fn, 'function' );

assert.not

Using assert.not*() indicates one of three problems:

  • The software is unreliable. (Unsure what value to expect.)
  • The test uses an unreliable environment. (E.g. variable input data, insufficient isolation or mocking.)
  • The author is lazy and uses it as shortcut for a proper comparison.

Common example:

var index = list.indexOf( item );
// Meh
assert.notEqual( index, -1 );
// Better?
assert.equal( index, 2 );

I’ve yet to see the first use of these assert methods that wouldn’t be improved by writing it a different way. Though I admit there are limited scenarios where assert.notEqual can’t be avoided in the short-term (e.g. when the intent is to detect a difference between two return unpredictable values, e.g. Math.random).