Update 11-Feb-2013: After some feedback, I would like to clarify what I am talking about here: I am talking from experience in applications not purely written in JavaScript: for example a MVC application written with say C# with JavaScript added to pages.
I’m really not a big fan of Jasmine JavaScript unit tests for applications not written purely in JavaScript. Here’s why:

Most modern web applications use JavaScript as a way to provide client side validation and interaction. Most of this JavaScript manipulates the Document Object Model (DOM) of the browser, therefore the JavaScript is coupled to the DOM using ids or classes of elements.
As most web pages are dynamically rendered by the server, Jasmine, the JavaScript unit test framework, can’t run against the ‘real’ DOM as it appears in the application, so what it does is duplicates parts of the DOM to test the JavaScript is working properly based upon this duplication.
As there’s no reliance on the real application or its DOM, these tests run super fast, you can run thousands of JavaScript tests in seconds which is pretty amazing.
The problem becomes that over time the real DOM in the application is changed but the Jasmine tests and its own duplicated DOM is not! This means that often I find that all Jasmine tests pass (as they have to for a new version to be deployed to QA) but the JavaScript doesn’t work in the application because an id or class name has been changed and someone ‘forgot’ to update the Jasmine tests.
Tests that don’t pick up valid errors are worthless, and I continually find myself getting annoyed that all the Jasmine tests have passed, but JavaScript is broken and our application doesn’t work.
Another downside is that Jasmine tests are only as good as the JavaScript engine they are run against. We run our Jasmine tests in a headless PhantomJS browser, which is fast, but most of our JavaScript bugs are found in Internet Explorer, particularly earlier versions of it, so Jasmine tests again are worthless.
I don’t know of a way to overcome these downsides to Jasmine that I have mentioned. What we do have is a suite of end to end acceptance tests that run in 5 different ‘real’ browsers that check the JavaScript works correctly. Whilst these take 8 minutes to run per browser, they pick up a lot more JavaScript issues than Jasmine.
I am not still not sure whether it is worth investing the time and effort in Jasmine tests when they don’t provide sufficient confidence that our application ‘works’.
What have others experiences been with Jasmine JavaScript unit testing?
Do you test drive your javascript or add unit tests afterwards?
A bit of both.
I think the issue is when application code is refactored using TDD and the Jasmine tests are not.
If a team is refactoring application code but not the unit tests, then it’s not really TDD.
Jasmine may not be suitable for the scenario you described. However, a lot of dynamic web apps are now developed based on Javascript frameworks such as Backbone.js, not directly base don JQuery/DOM manipulations.
Jasmine can help to unit test the logics/objects based on the javascript frameworks. So, I believe that it is still a good one, but has to be used properly.
http://tinnedfruit.com/2011/03/03/testing-backbone-apps-with-jasmine-sinon.html
Agree in this regard.
As for mixing in JavaScript into an existing MVC application: this is where DOM duplication is a problem.
I have a feeling that you are mixing different testing types. Unit testing and Acceptance testing. Unit testing doesn’t have to prove that in every possible environment your code will work. Acceptance tests does. Jasmine works great for Unit/Integration testing but not so well for Acceptance testing.
As for ids dependencies, I have a strong feeling that it is actually more design flow then Jasmine problem. It seems that you have the same variable defined in two different places (javascript and html) no wonder they are becoming inconsistent over time.
I’ve written short blog post describing my point of view on this subject:
http://agilefront.blogspot.co.uk/2013/02/one-gun-many-enemies.html
The reason for doing TDD is not to end up with a bunch of tests. Unit testing is just one aspect of QA – it doesn’t guarantee defect-free code.
TDD is primarily about esign, with the aim being to build classes with clean interfaces and minimal dependencies, making the code easier to maintain, extend and debug.
If you’re rely on integration-level tests you’ll never be able to get into a red-green-refactor cycle with short enough feedback.
Unit tests or integration tests alone are never enough – it’s all about getting the balance right.
“JavaScript doesn’t work in the application because an id or class name has been changed and someone ‘forgot’ to update the Jasmine tests.”
Is this Jasmine fault that someone didn’t update the test? Come on, what kind of argument is that?