Wednesday, January 29, 2014

Zero to Build Failed in 20 minutes

In the process of learning Node.js, I elected to build some basic projects in the language, but also to leverage source control (GitHub, of course) and Continuous Integration. The obvious choice for this project is Travis CI, which provides free build testing for open source repositories.

First, you'll need to setup a .travis.yml. I shamelessly reviewed a few favorite node project's configurations along with the Travis CI help before settling on the simple, concise:

language: node_js  
node_js:  
  - "0.11"
  - "0.10"
  - "0.8"
  - "0.6"

That's more than enough testing, as I'll probably only use the 0.10 branch and 0.11 once it's released.
So what does Travis CI do for Node builds? Well it executes npm test, by default. What on earth does that do? Well, there's really nothing helpful in the documentation, but again, by perusing a few favorite projects it executes a script in the root of the project named test.js or all scripts in a folder named test.

Alright, so then just save an empty file named test right? Not so much. The easiest way to get started with some test driven development is to assert what you expect your functions to return for certain known values.
Consider a simple Fibonacci series:

module.exports = function fib(n) {  
   if ((n === 1) || (n === 0)) {
      return n;
   } else {
      return fib(n-1) + fib(n-2);
   }
}
And then require the module and assert in test.js:

// Import libraries
var fib = require('./fib.js');  
var assert = require('assert');

// Exercise fib
assert.equal(fib(4),3);  
assert.equal(fib(5),5);  
assert.equal(fib(6),8);  
assert.equal(fib(7),13);  

At this point, a git push to the repository, provided Travis CI is enabled for it, will result in the above code being executed in Travis CI's build environments and any uncaught exceptions will fail the build.
But consider this, if I purposely throw an exception then catch it, does my build fail when the application experience isn't actually passing?

module.exports = function buildHyjinx()  
{
try  
  {
     if(true) throw "empty";
  }
catch(err)  
  {
     console.log(err);
     return -1;
  }
}

Wait a minute! A build passes because we handled an exception appropriately? Yes. So build real life tests and include testing for functionality you don't yet have. Then fail your build, on purpose, or you'll never know what you haven't done yet.

No comments:

Post a Comment