Unit testing blog posts

A way to unit test JavaScript code inside Markdown blog posts.

I use a lot of code examples in my blog posts. This is normal, because this blog is about software and needs examples to be useful.

typical post with code sample

1
2
3
4
// the add function returns sum of numbers
add(2, 3); // 4
// it also concatenates strings
add('foo', 'bar'); // foobar

The worst happens when I notice a syntax or result error in one of my blog posts. For example in the code sample above the expected value // 4 should be // 5. The errors happens for the same reason syntax errors happen inside API documentation: the examples are usually written inside the comment blocks. They are never linted or tested, and get out of sync with the rest of the code pretty quickly.

I solved this problem by unit testing my blog posts. Only instead of running code inside the post, I have separate source files for each blog post. They are usually in the form of unit tests, or at least have plenty of assertions.

Step one: write initial post and leave code blog either empty or with initial text. Give the code block title using ### line

add.md
1
2
3
### add example

add function adds things

Step two: write unit test using QUnit / BDD / plain console.assert syntax. Give the unit test same name as the code block title.

add.js
1
module.exports = function(a, b) { return a + b }
add-test.js
1
2
3
4
5
6
7
8
// using QUnit
var add = require('./add');
QUnit.test('add example', function () {
// add function returns sum of numbers
QUnit.equal(add(2, 3), 5);
// it also concatenates strings
QUnit.equal(add('foo', 'bar'), 'foobar');
});

Step three: make sure the unit test passes using gt, runs natively under Node and provides code coverage via istanbul

gt add-test.js

The tests pass

test results

Step four: update the sample code inside your blog post using xplain

$ xplain -i add-test.js -o add.md

This transforms QUnit-specific test syntax to human form

updated add.md
1
2
3
4
5
6
### add example

// add function returns sum of numbers
add(2, 3); // 5
// it also concatenates strings
add('foo', 'bar'); // 'foobar'

Conclusion

Unit tests are useful, and they can be used for variety of tasks. Making sure your blog posts are correct by going from tests to Markdown is easy, and I plan to expand the assertion syntax supported by xplain. Right now, it supports QUnit / gt / console.assert / some built-in Jasmine matchers. If you would like to see something new in xplain, please open an issue.