(Testing with) less is more 07 Dec 2011

I had my first real experience with unit testing in my software engineering course as a freshman. In this course we challenged our freshly developed skills in Java programming. Do our programs as we have told them?

We did our tests with JUnit, a pretty nice testing framework for the java vm.

Lately, I’m experiencing with node.js. Back in the Java world, I was left with one, maybe two options on how to test my programs. In JavaScript I have an numerous amount of testing frameworks at hands. All try to achieve the same thing, but slightly different.

Well in the tradition of xkdc I will present my own unit testing framework

standards

Well… No.

While thinking which framework suits my testing best I discovered that the only required part of testing is an integral part of node: assert

Let’s try to test without an framework.

Yeah sure, but sometimes I need my friends setUp and tearDown

No need for a framework, the only think required is a file liked this

module.exports =
    setUp: () -> hereIReturnAnObjectWithAllRequiredMethodsMyTestNeeds
    tearDown: () -> thisObjectIsOfCourseReusableAboutAllTests

And what about the structure of my tests? I don’t want one big file with a long lists of assertions. What about using the things we have: directories and files. Each test is in own file. This makes not only the tests small in size (and thus more readable). You can also put the description directly in the filename. Another advantage is that you can cherry pick the tests you want to execute (perhaps you have some lengthy integration tests and only want to test an part of the application).

How should I test asynchronous code?

With the above tools it wouldn’t be possible to detect the defect in this code:

storesValue = (value) -> (next) -> # upps comment instead of this: next value

If javascript has to code to run it will end the process.

storeValue(5) (result) -> assert result, 5, 'wrong result returned'

In this code the callback would never be executed, and the assertion couldn’t be triggered.

So we need an mechanism to verify that a specific part of our code has been executed before we put our process to an end.

Why not extract test.done from all the big asynchronous frameworks and modify our test a bit

done = require('done')()
storeValue(5) (result) ->
    assert result, 5, 'wrong result returned'
    done()

And this method can be built in 4 lines of code (trust me).

Advantages

Disadvantages

So I would invite all fellow coders to rethink our development process. Do we really need all the big tools and frameworks we use everyday or are we just pulling all the junits of the world around up to now, because we did need them long ago and got used to them?