I got through available testing frameworks for Javascript and decided on Jasmine. Why? Mainly because its syntax - BDD style which is fashionable this season. Second reason is that it has really cool documentation. Finally, basic set up was painless to me.
Let's look at basics - what I expect from different types of tests and how Jasmine fits into those requirements:
1. Unit Testing
Aims- Shoot them one by one
(structure your code so that it is easier to maintain) - Be sure you kill with every shot
(verify small bits of code to nail down bug issue) - Kill them all
(verify edge cases) - Kill them quick
(provide fast feedback on issues)

- Fast shooting - the faster you shoot, the more enemies you will kill
(unit tests must be blazing fast) - Reliable - your gun is stuck and you are dead
(when unit tests are brittle you will stop depending on them) - Always close
(unit tests are your gun, so you must be able to run them all locally)
Jasmine works great for all those aims, as it is really fast and it allows you to stub both objects and DOM elements. Keep in mind that Unit Testing is useful only if you either write new code or refactor old one. Do not ever try to write UT for a ready code which you don't intend to refactor. It's like shooting dead. You simply cannot kill them with another bullet.
2. Integration Testing
Aims- Beware of the hidden sniper
(test against external dependencies like files, databases, network services)
- You are part of your squad
(verify that components of the application work well together)
- Observe the environment
(try to use depenedencies as close to real problem as possible e.g. static file, database with test data, test version of a service) - Point in the right direction
(do not try to test your stack top-down, instead concentrate on interfaces and adapters that you could not test in unit tests)
3. Acceptance Testing
Aims- Confirm you are fighting the right war
(show specification to your product owner/manager/client) - Keep clean supply routes
(test the functionality of your up with full set up and all dependencies) - Find hidden mines
(test your application in all environments you deploy your application to)
- Speak in their language
(use tool which allows writing tests in natural language e.g. Cucumber or SpecFlow) - Take your time
(those tests will be slower, so accept that you will not always run them locally) - Spend your resources wisely
(acceptance tests are naturally much more brittle then other types of tests, so try to keep their number reasonably small)

Conclusion
I find Jasmine extremely well suited for unit and integration testing. I wouldn't use it for acceptance tests as there are quite few better tools for that job.Post Scriptum (on DOM dependency)
On his blog Alister Scott also complains about integration issue between his server-side code and client-side code. His experience is that changes to ids and classes in mvc application result in not working javascript. The issue is serious and shows one important mistake which is hardcoding dependencies. Ids and class names are configurable details and Javascript code should be agnostic of them. To illustrtate let's look at test case for a very simple code from my pet-project:
describe("GameController", function(){
describe("During Initialize", function() {
var view;
var subject;
beforeEach(function() {
setFixtures("<div id="myid"></div>");
subject = new GameView();
subject.CreateFabricInDiv("#myid");
});
it("creates fabric in div", function(){
expect($("#myid")).not.toBeEmpty();
});
it("holds pointer to canvas", function(){
expect(subject._canvas).not.toBe(undefined);
});
});
Do you see how "#myid" parameter is passed into method call? We moved configuration detail out from Javascript code. In my opinion it is simplest solution to Alister problem. This will enable keeping ids/classes consistent between code which generates them and Javascript that uses them. It also helps with code re-usability as you can use the same code on two separate pages with differing ids!
Agree. Goos post, very f** good web design :)
ReplyDeleteExcellent info! I have heard that mixing Jasmine + Selenium is a killer combo, but I'm not sure I can tell precisely when to use one or the other. Any help in this matter will be much appreciated, as well as any tips on good tutorials for integrating Selenium in everyday testing work.
ReplyDeleteThanks in advance and keep the good fighting!