Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

At work, we've just started on a heavily Javascript based application (actually using Coffeescript, but still), of which I've been implementing an automated test system using JsTestDriver and fabric.

We've never written something with this much Javascript, so up until now we've never done any Javascript testing. I'm unsure what exactly we should be testing in our unit tests. We've written JQuery plugins for various things, so it's quite obvious that they should be verified for correctness as much as possible with JsTestDriver, but everyone else in my team seems to think that we should be testing the page level Javascript as well.

I don't think we should be testing page level Javascript as unit tests, but instead using a system like Selenium to verify everything works as expected. My main reasoning for this is that at the moment, page level Javascript tests are guaranteed to fail through JsTestDriver, because they're trying to access elements on the DOM that can't possibly exist.

So, what should be unit tested in Javascript?

share|improve this question
3  
You isolate any javascript code you've written into modules. Then you simply test the inputs and outputs of those modules. Any modules that deal with the DOM means you have to test the DOM. Use a better tool then jsTestDriver. –  Raynos Nov 15 '11 at 12:36
    
You should be unit testing business logic. If your business logic and elements on the DOM are intertwined then you have a design flaw. Abstract out as much business logic from the page elements as possible so that it can be properly unit tested. For DOM element interaction verification you should be using Selenium. –  maple_shaft Nov 15 '11 at 12:43
1  
@NathanHoad You write unit tests that get run in the browser itself, nodeunit, qunit and jasmine are sensible tools. When running in the browser you have the DOM. You could use a tool like testling to automate browser testing. –  Raynos Nov 15 '11 at 13:09
1  
Thanks. I was looking toward jsTestDriver as it claimed be able to run in the browser, which, while technically true, I've discovered isn't the same as running with QUnit. I've been working on my own tool at the moment that uses QUnit, with a custom Django debug toolbar panel. Using Selenium I'll be able to detect failing tests. Also, I doubt my boss would pay for testling, although it does look pretty good! –  Nathan Hoad Nov 15 '11 at 13:17
1  
related: How do you unit test your javascript –  gnat May 31 at 18:59
show 7 more comments

3 Answers 3

up vote 3 down vote accepted

Test everything you can.

Pure logic can be tested easily.

If your code interacts with the DOM or the network, it's much harder.

If you can abstract out a piece of code to work on an arbitrary DOM element instead of a specific one, then you can test it more easily. (Make the element to work on a parameter).

Code that uses Ajax can be tested by simply calling the callback function with fixed data. I've had some tests where I overwrote $.ajax with my own function. Just make sure you put the real one back when you're done!

What you'll find is that "page level javascript" really means, "tightly coupled code," and if you decouple the parts of the code, you can test them independently.

(Selenium is not a unit testing tool. It's great for high-level scenarios, but you can't test-drive with it, and it doesn't work in an isolated environment.)

share|improve this answer
    
jasmine can mock function calls and response data, you might look into that instead of overriding functions. –  Steve Nov 15 '11 at 16:32
    
I should clarify - we have functions and such on each page. I was talking more about testing the code that executes inside $(document).ready(...). –  Nathan Hoad Nov 15 '11 at 22:47
1  
It's all a matter of how big that ... is. :-) I feel like you should be able to get that down to a single named function that is also tested. Then your untested code is a single line. (Now that's a goal, not a given. In practice I've always had more than one line of untested code.) –  Sean McMillan Nov 16 '11 at 13:47
add comment

Test algorithms. GUI-closely related parts are more depended on specific browser so have to be tested using selenium-like utils.

Your code, of course, must contain algorithms as an isolated pieces of code, if it doesn't then unit testing is almost impossible.

jquery plugins, btw, are not easy unit-testable.

share|improve this answer
    
All good points! I agree that they're not easily unit testable as well, depending on how they're written. –  Nathan Hoad Nov 15 '11 at 12:58
add comment

I used to work with Java and from what I see unit testing Java is easier than unit testing JavaScript because Java is more rigid.

I'm sold on that test-driven development is the best thing so I'm also exploring how to unit test JavaScript. In Java I've mocked out the code that made connection to the database, the Data Access Objects, and I compare that to the code in JavaScript that changes the DOM and the code that makes AJAX calls to the server.

What I'm getting at is that it seems to me that what should be tested is the logic explicitly. For example, you don't want to make an AJAX call when you run unit tests because (a) you need the server to be running and (b) it is slow and one of the guidelines of unit testing is that it needs to be super fast so that the developers don't avoid running them like every minute.

Another guideline is for the continuous integration process to send an e-mail saying that it found a unit test that failed.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.