I’m sure with size, complexity and sheer number of JavaScript applications and frameworks that have been poring into production over the last few years, there must be a lot of developers out there putting serious effort into testing. Despite this there seems to be quite a low amount of information on the web about the tools and frameworks that are available. So I thought I would share the with you my own personal experiences when it comes to the tools that are out there.

Spec and Testing Frameworks:

This is an area JavaScript has pretty much got nailed with two great offering for both the xUnit and xSpec/xBehave crowds.

JSSpec

I really don’t know what I would do without this great BDD framework written by 강규영 (a.k.a Alan Kang). It follows the standard semantics of BDD and has an extremely natural DSL which I’ve seen developers get up and running with in under ten minutes.

describe('Plus operation', {
    'should concatenate two strings': function() {
        value_of("Hello " + "World").should_be("Hello World");
    },
    'should add two numbers': function() {
        value_of(1 + 2).should_be(3);
    }
});

The spec runner is also quite something to behold as it runs through each spec within the suite for your story. I still believe that a GUI or web interface as is the case in JSSpec is a very powerful tool when conveying the value of thorough testing to the product owner. I even had a product owner bring stakeholders into the office who have no idea about BDD or any software development practices for that matter just to show them the tests.

There are a few ‘quirks’, such as extending some of JavaScript’s base type classes and a small sprinkling of global variables but that’s a small price to pay in the name of elegant DSL, besides the code is very readable which means you can easily get in there and make some tweaks if you would prefer a slightly less flowing DSL in return for a clean namespace.

JSUnit

I used this JavaScript port of JUnit for a long time before I discovered BDD and then JSSpec. It is a very well supported framework and is very good at what it does, but as is the problem with all of the xUnit family of test suites it doesn’t have a clearly defined set of semantics for testing other than assertThis and assertThat so therefore can’t really have a DSL, so instead we have a collection of functions and a lot of room for developers to fill in the blanks.

function testPlusOperation() {
    assertEquals("Hello " + "World", "Hello World");
    assertEquals(1 + 2, 3);
}

For people who are experienced at testing it works great, for those who aren’t things can get very ugly, very quickly. It also has a nice test runner, but the green progress bar just doesn’t have the same impact in conveying the sheer weight of  the tests it is running through in the same way JSSpec does, it is very functional but isn’t going to impress the stakeholders. To sum up as I said already I can’t knock the software itself, it does exactly what is says on the box.

Mocking Frameworks:

Unfortunately the two offerings for mocking frameworks aren’t nearly as strong as their spec/test counterparts discussed already. They both have their ups and downs but one major flaw they both share is an inability to reliably get the public methods from your class (function) constructors and this is in part a JavaScript problem. In order for the mocking frameworks to retrieve the public methods which may be contained within your classes constructor rather than its prototype, the class has to be instantiated so that the the properties can be iterated through to see if the expected method can be found there. This is great, but the problem comes when your class is dependent on an argument passed in to the constructor. Like so:

function MyClass(dependancyObject){
    this.foo = dependancyObject.someMethod();
}

When we pass MyClass over to be mocked, the mocking framework is not going to pass in an argument that implements the interface of the dependency object and therefore will raise an exception. Yes I already know there are umpteen good JavaScript coding practice that will avoid this problem, but the point is that a mocking framework should work as long as the code for my class is valid, regardless of whether it follows good practices or not.

JSMock

JSMock is cool little mocking framework with a very sexy DSL, the only problem is that it isn’t fully featured. It allows for you to add return value expectations to your mock object but does not allow you to place an expectation on the number of times the method will be called. This often results in this kind of thing:

myMock.expects().myVeryWellUsedMethod().andReturns(something)
myMock.expects().myVeryWellUsedMethod().andReturns(something)
myMock.expects().myVeryWellUsedMethod().andReturns(something)
myMock.expects().myVeryWellUsedMethod().andReturns(something)
myMock.expects().myVeryWellUsedMethod().andReturns(something)
myMock.expects().myVeryWellUsedMethod().andReturns(something)
myMock.expects().myVeryWellUsedMethod().andReturns(something)
myMock.expects().myVeryWellUsedMethod().andReturns(something)

When what I REALLY REALLY want to do is this:

myMock.expects().myVeryWellUsedMethod().times(8).andReturns(something)

Or if we were a bit naughty and had extended the Number.prototype, maybe even something like this:

myMock.expects().myVeryWellUsedMethod().8.times().andReturns(something)

But what we all to often end up with is this:

// :-(
var myStub = function(){
    myVeryWellUsedMethod: function(){
        return something;
    }
};

There is also no support giving expectations to the parameters passed to methods of the mock object. Personally with my normal usage patterns I seem to be able to live with that, but I know that for other people it is a big issue. I know I sound like I’ve come down quite hard on JSMock but that’s only because I really love the DSL and know that with just a couple more features it could have been perfect.

Mock4js

While JSMock falls short on features, I very much doubt you will hear many people laying the same charge against Mock4js. It has everything you would expect from a fully featured mocking framework, we can set expectations for our mock methods on the arguments passed, the return values, the number of times we expect it to be called and can also quickly knock up stubs if you are that way inclined.
But don’t start getting too excited quite yet. The DSL is not very smooth, meaning it will take a few days before you are writing mocks without having to check the docs, but this is a small issue compared to the havoc it causes in your namespace. In order to be able to create mocks you need to make a call like so:

Mock4JS.addMockSupport(this);

This method then proceeds to decorate whichever namespace ‘this’ is referring to (usually global or that of your testing framework) with a sh!t load of methods. The first time I used it was within in the JSSpec namespace and straight away there was a collision.
“And that’s all I have to say about that”. Forrest Gump.

Code Coverage Tools

Although I’m not anywhere as religious about code coverage as I am to other aspects of testing, especially in JavaScript where inconsistencies often mean you have whole modules that were designed only for a single browser, SVG/VML type applications spring to mind. This means a file can receive 100% coverage in one browser and 0% in another. Despite these glaring inconsistencies code coverage is still useful to find any large gaps, especially if you are a lead developer working on a large code base with a large team where monitoring manually can be a real pain.

JSCoverage

JSCoverage is a cool command line app that runs through your projects folder and recreates the project in a new folder only with some added ‘special sauce’. You will now be able to point there web interface to the HTML page of you test suite and get back a detailed coverage report.


The Good (things that didn’t work very well for me last time I tried):

  • All of my usb devices were recognized straight away
  • Connecting to wireless networks is effortless
  • Linux Skype now has video calls
  • Eclipse works with all of my favourite add-ons
  • Google Earth
  • My ATI graphics card
  • Bluetooth

The Bad:

  • Eclipse (never known for its legs) is even slower than on windows
  • Fonts still look a bit skanky without a lot of messing around
  • OpenOffice still butchers five out of every ten .doc files I try opening

The Ugly:

  • It took me about three days of command line hacking to use dial-up via my 3G phone

Summary:

Still not perfect but I think for me at least it now has the edge on Windows.


Scrum Master: He (team member) actually believes his opinion is valuable.


Dear diary, well I guess it’s that time of year again, my annual bout of: “F%*ck you Windows, it’s over, and this time I mean it, pack your crap and get out!”. This time the provocation is a virus that is so persistent, that even after three weeks and multiple treatments it still keeps reappearing. Yep, time to trade in that fat, winging and extremely bloated package for a more slender cost effective model.

So I have now asked Ubuntu, my long standing and very hot bit on the side to move in with me full time. She’s slim, attractive and lets me use her without protection. All my mates are really impressed! But this is now a well traveled path, I’ve been with Ubuntu before, come to think of it, I’ve even been with her sisters Fedora and Debian a few times too and I already know there’s a flip side to this coin.

Last time we had a whirlwind romance, I had to eventually give her the boot because after a grueling 72 hour marathon session in my spare room, she STILL could not figure out how to access the internet on my mobile phone. Anyway that’s water under the bridge, she’s matured a lot since then and I think this time we can really make a go of it, besides if I go back to Windows after telling all my friends what a fat virus riddled skank she is, I won’t be able to show my face in the pub ever again.


Since moving into the new office we’ve been trying really hard to set things up in such a way that a culture of learning and knowledge sharing is created. In addition to pair programming, a reading area and an ever growing library, we’ve set aside three hours of group study time a week. As with all things under Scrum, the time, duration, date, topic and existence of the study periods was voted on by the development teams. We settled on three sessions a week – Tuesday: GoF Design Patterns, Wednesday: Open Mic(anybody can present anything) and Thursday: JavaScript.

Miika and I are leading the design pattern session and I’m leading the JavaScript session. So what is the obvious progression from this……?

Well I’m guessing you’ve already read the title so I doubt I’ve built up much suspense – Design Patterns in JavaScript!

We are using Head First Design Patterns as our study guide as it is much easier to digest than any of the other books are, especially for people who speak English as a second language. So the plan is to post each one of the examples from the book implemented in JavaScript, I’m then going to post those example to Wikipedia as JavaScript is currently not very well represented in most of the design pattern entries.

I’m not the first person to cover the subject, in fact Ross Harmes, Dustin Diaz have already written an excellent book on the subject, but I am going to take a slightly different angle. The plan is to where ever possible avoid building constructs that try to imitate the constructs of other languages, so I will be avoiding using helper methods to mimic interfaces, abstract classes and other constructs and instead embrace JavaScript’s dynamic nature.

Here’s the pizza example from the Head First book in JavaScript:

//Class to be decorated
function Coffee(){
    this.cost = function(){
        return 1;
    };
}

//Decorator A
function Milk(coffee){
    this.cost = function(){
        return coffee.cost() + 0.5;
    };
}

//Decorator B
function Whip(coffee){
    this.cost = function(){
        return coffee.cost() + 0.7;
    };
}

//Decorator C
function Sprinkles(coffee){
    this.cost = function(){
        return coffee.cost() + 0.2;
    };
}

//Here's one way of using it
var coffee = new Milk(new Whip(new Sprinkles(new Coffee())));
alert( coffee.cost() );

//Here's another
var coffee = new Coffee();
coffee = new Sprinkles(coffee);
coffee = new Whip(coffee);
coffee = new Milk(coffee);
alert(coffee.cost());

As you can see by the procedural code using the decorator pattern in JavaScript is much the same as its usage in other more orthodox languages, the big difference is in the implementation of the pattern. As you can see there is no defined interface. JavaScript has no Interface construct, the answer to this as with many other dynamic languages is duck typing (Note: Wikipedia needs a JavaScript duck typing example).

Duck Typing shifts the responsibility of making sure an object meets an interface from the creator to the receiver. Which is exactly what is happening above, the decorators receive an object which needs to implement the coffee interface by having a single method named cost(). If the object passed in does not have a method called coffee, then an exception will be raised by the JavaScript interpreter at runtime.

I guess what I’m trying to say is the main thing for me when addressing design patterns is that the ‘what’ (behaviour) is more important than the ‘how’ (implementation). In JavaScript the how is duck typing, in Java the how is an interface, but who cares? The important part is the what, and in both if we try to utilize an object which doesn’t meet our interface then an exception will be raised.




RSS /their/stuff/

  • An error has occurred; the feed is probably down. Try again later.

/del/icio/us

Follow

Get every new post delivered to your Inbox.