BusterJS vs Chai/Mocha

BusterJS, a node.js-oriented test framework, is notable for having a lot of ways to run tests, including one where it fires up an HTTP server that your browser connects to, as well as a way, seemingly, to attach several browsers to a single running test harness. Having opted against exploring the whole node.js / browser module dichotomy up until now, I skipped all of that stuff and went straight to the instructions for just running the thing in a browser. (I should note in passing that the test-runner Mocha, covered earlier, also has a lot of non-browser-focussed running modes which I didn’t cover, among which the most intriguing is the Nyan Runner).

Anyways, the browser stuff was quite easy to set up, and I returned my focus to writing tests in the BusterJS idiom.  As it turned out, there wasn’t all that much different about it.  BusterJS comes with a BDD-oriented test mode which functions almost exactly like Mocha’s does, and it also sports a BDD-flavored assertion style which is very similar, if a bit less tricksy in its syntax.

To illustrate, here’s a snippet of the Mocha/Chai tests:

describe('WeightedList', function() {

  describe('Constructor', function() {

    it('should succeed with no arguments', function() {
      expect(new WeightedList()).to.be.ok;
    });

    it('should throw errors on bad inputs', function() {
      var badConstructor = function() {
        return new WeightedList( {'wrong': 'field names'} );
      };
      expect(badConstructor).to.Throw(Error);
    });
  });
});

And here is their BusterJS equivalent:

var spec = describe("Weighted Lists", function() {

  describe('Constructor', function() {

    it('should succeed with no arguments', function() {
      expect(new WeightedList()).toBeDefined();
    });

    it('should throw errors on bad inputs', function() {
      var badConstructor = function() {
        return new WeightedList( {'wrong': 'field names'} );
      };
      expect(badConstructor).toThrow();
    });

  });
});

As you can see, the broad strokes are virtually identical. The main difference I’ve noticed is that Chai uses a little more trickery to get its assertions into a quasi-DSL style, with statements like result.should.have.length(1); and new WeightedList().should.be.ok; as opposed to BusterJS’s more conventional expect(result.length).toEqual(1); and expect(new WeightedList()).toBeDefined();.  While I appreciate the vigor with which the Chai folks were able to bend Javascript’s syntax to their will, I actually find the more conventional BusterJS syntax to be a little easier to read, since it looks basically like I expect Javascript to look.

Overall, these assertion frameworks both seem adequate for testing Javascript code. I’m really not thrilled about the way one tests code for exceptions in either language, where it’s necessary to pass in a function which is expected to throw an error, but I can’t really think of a better way to do it in Javascript. I’m going to continue porting the tests over to BusterJS, but I don’t know that I’ll have all that much more that’s interesting to say about it. If you’re interested in the nitty-gritty, the details can be found by contrasting the Chai and BusterJS assertion documentation.

I should probably also note in passing that the particular uses I’m putting the testing frameworks through are a little unusual. Most people writing tests won’t be testing a pure-javascript library with no user-interface whatsoever, and a lot of the appeal of the various frameworks seems to be the integration they offer with various other pieces of the Javascript ecosystem.

With that in mind, my next task is to finally figure out what the whole Javascript module system is all about, and likewise to figure out how I can package the library I’ve got into something usable in a node.js context. Meanwhile, based on a preliminary reading of the AMD vs CommonJS pedagogy in the blogosphere, my idea of just including the library code on a web page via a <script type="text/javascript" src="js-weighted-list.js"/> tag is laughably naive, and I’ll need to add a compilation step in there, because what is Javascript if not an Ada-style B&D language which benefits from the intense scrutiny of static program analysis?

In any event, adding a compilation step will probably give me a ready excuse to jump over to CoffeeScript.

Advertisements
Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: