2

I'm starting to delve into some work with JavaScript and i'm trying to get a feel for how I should be writing testable JS code. My background is primarily Java which i'm quite comfortable with but I have no JavaScript experience. after some reading, I was going to use js-test-driver as my unit test framework, but I am open to suggestions here as well. With Java, my approach has always been breaking things down into small methods which accept something and return something... With JavaScript, I figured I would take a similar approach by separating any DOM manipulation and the actual logic into 2 separate functions. For example:

function sumValues(valA, valB) {
return (valA + valB);
}

function displayResult(result) {
document.getElementById('result').innerHTML = 'result';
}

So, any business logic would be easily testable.

Am I on the right track here or is there a better way to do things? Any recommended reading on this topic that is JS specific? Thanks for any ideas

RandomUser
  • 4,140
  • 17
  • 58
  • 94
  • 1
    Just wondering - what are you trying to do with that `return (valA, valB);`? In Javascript, the comma operator works like this: `(statement, return)`, so you're basically evaluating `valA` and then returning `valB`. – jeremy Aug 26 '12 at 20:22
  • Sorry about that, I updated it with a +, typo – RandomUser Aug 26 '12 at 20:23
  • 1
    I have no experience doing this, however, this feels absolutely correct to me. Something you may want to look into that would actually help a lot especially coming from a Java background would be functional paradigm programming (which it sounds like you've inched towards as it is) because javascript is completely capable of being a functional lalnguage, and unit testing is a huge driver in the functional paradigm so you could look for reading materials on unit testing in the functional paradigm. – Jimmy Hoffa Aug 26 '12 at 20:23
  • 1
    Here's a thread that details what I'm referring to, including the fact that you've stretched closer to functional in your java code: http://news.ycombinator.com/item?id=493963 – Jimmy Hoffa Aug 26 '12 at 20:25
  • I guess `function displayResult(result){document.getElementById('result').innerHTML = 'result';}` should be `function displayResult(result){document.getElementById('result').innerHTML = result;}` (without quotes) – Oriol Aug 26 '12 at 21:14
  • 1
    Your approach to organising the code for testability in this way sounds good, to me. I use jsTestDriver for specifying assertions and I use Sinon.js for spying and stubbing method calls. The two together make a very powerful TDD tool for JavaScript. – Greg Ross Aug 26 '12 at 22:14
  • Thanks Jimmy and Greg for the feedback and suggestions – RandomUser Aug 27 '12 at 12:19

1 Answers1

3

Breaking code into logical units still applies in JavaScript of course. As to how exactly you'd structure your code and organize reusability, there are many different ways to choose from - too many to list here and also a matter of personal preference. From prototypal inheritance, to pseudo-classical inheritance; using frameworks like backbone.js, angular.js, require.js, yui, google closure...

Regarding your example you'd probably start separating your code into views and controllers which are testable separately, and have only the view manipulate the DOM. I'd check out backbone.js for more.

A book that really helped me get started with test driven development in JavaScript (and also learn about JavaScript at the same time) is Test-Driven JavaScript Development by Christian Johansen.

I'm using JsTestDriver, it's a great software and definitely good to use. But before using it large scale I'd evaluate other products too, because development in JsTestDriver has been going really slow recently.. Buster.JS looks promising. Another interesting runner is Testem which allows you to use different test frameworks, like Mocha and Jasmine.

I can also recommend Sinon.JS as mocking toolkit.

meyertee
  • 2,211
  • 17
  • 16
  • One build - since Buster.JS is still in Beta (and doesn't currently work on Windows), going down the JsTestDriver route for now looks safe, since Buster looks like it provides a runner for JsTestDriver tests: http://docs.busterjs.org/en/latest/extensions/buster-jstestdriver/ – quux00 Oct 28 '12 at 02:34
  • Another test runner I'm currently experimenting with is [Testem](https://github.com/airportyh/testem). Great if you prefer the BDD syntax, and it seems to have Windows support. No js-test-driver compatibility though.. there's a nice introduction [here](http://net.tutsplus.com/tutorials/javascript-ajax/make-javascript-testing-fun-with-testem/). – meyertee Oct 29 '12 at 11:50