Testing Memetica

In Memetica, run npm run test to execute the tests once or npm run test:watch to run a simple test watcher.


Since Memetica is just a bunch of scripts strung together by stdin/stdout, the project's tests are written to exercise these individual scripts and ensure that the scripts produce reasonably-correct output given some input.

Tests are written with node-tap so that anyone can consume them according to TAP.

We can output with any of node-tap's many reporters, e.g. npm run test -- --reporter=nyan.

pictured: the venerable nyan reporter

pictured: the venerable nyan reporter

The First Test

The first reasonable thing I thought to test was document columnization.

I'll talk about it a bit. Here's the test in its entirety:

var tap = require('tap');
var exec = require('child_process').exec;
var fs = require('fs');

tap.test('produces reasonably well-formed column elements from `|||` in input', function(t) {
  var command = 'cat test/column_document.md | node columnize.js';
  var expectedOutput = fs.readFileSync('test/column_content_columnized.md', {
    encoding: 'utf8'

  exec(command, function(error, stdout, stderr) {
    t.equal(stdout, expectedOutput);

So all that I'm doing here is taking the script that handles a thing that Memetica actually does.1 We run that script with simple input2 that should transform into different output3 and assert that the results of the script are the same as our expected output.


Nothing about how the work is done is assumed. This frees us to change the implementation later, but the important business logic that is unique to Memetica is crystallized here in the test, potentially forever (or at least however long it is useful).

If we ever accidentally break this important functionality, the test will fail. We will know immediately, which will prevent us from going too far down a path that is harmful to the system.

These benefits aren't actually unique to Memetica, but it's easy to forget that this is why we write unit tests.

  1. Memetica does not actually do much, and we like it that way.

  2. Defined in test/column_document.md.

  3. Defined in test/column_content_columnized.md.

Share on: Hacker News Twitter