QUnit anti-patterns

Timo Tijhof
Feb 13, 2015 · 2 min read

Today, I’d like to challenge the assert.ok and assert.not* methods. I believe they may’ve become an anti-pattern.

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 using it as shortcut for a proper comparison.

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

  1. Less debug information. (Inaccurate 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, Promise, or other object) the test will not be able to catch this regression.

Common examples:

// Meh...
assert.ok( result );
assert.ok( obj.fn );
// Better.
assert.equal( typeof obj.fn, 'function' );
assert.strictEqual( result, true );

assert.not

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

  • The software is unreliable. (Value is indeterministic.)
  • The test uses an unreliable environment. (E.g. the input data is dynamic or variable, insufficient isolation or mocking.)
  • The author is using it as shortcut for a proper comparison.

Common example:

var index = list.indexOf( item );// Meh...
assert.notEqual( index, -1 );
// Better.
assert.equal( index, 2 );
// Even better?
assert.propEqual( list, [
'foo',
'bar',
] );

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

When calling a method such as Math.random() twice, one could use notEqual to assert the two return values differ. I still have my doubts about the value of such test, though. It’ll certainly be annoying when it randomly does produce the same value twice and cause a test failure. In the mission of test coverage, my recommendation would be to instead assert that calling the method did not throw an exception, and perhaps assert the type and length of the return value, without comparing the string content.


Originally published on timotijhof.net.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store