If you want to use “Jasmine”:http://pivotal.github.com/jasmine/ to unit test your Ext JS 4 application, there are a number of good resources available that can help you get started.
* “Unit Testing with Jasmine”:http://docs.sencha.com/ext-js/4-1/#!/guide/testing
* “Setting Up BDD With Jasmine and ExtJS 4”:http://www.dafishinsea.com/blog/2011/06/28/setting-up-bdd-with-jasmine-and-extjs-4/
* “Jasmine & ExtJS’ MVC: A Love Story”:http://jonathangrimes.com/2011/10/jasmine-extjs-mvc-a-love-story/
Most of these indicate they are for writing _unit_ tests, but few of them seem to focus on isolating the component or class to be tested. Some even go as far as to show how to load your entire @Ext.application@ for testing. Here I will show what I have done to unit test my Ext JS code using Jasmine.
Just as in all of the examples above, you will need to modify the @SpecRunner.html@ that comes with the standalone distribution of Jasmine. But instead of using a real @Ext.application@ or one made specifically for the test, you just need to set the load path (relative to the location of the @SpecRunner.html@) and wrap the call that starts Jasmine with an @Ext.onReady@.
function execJasmine() {
Ext.onReady(function() {
jasmineEnv.execute();
});
}
In addition, if you want to test custom UI widgets you can add an element to the body of the test runner page where you can later render the widget to:
With that in place, you just need to require the class you are going to unit test at the top of your spec. For example, here is @MyWidgetSpec.js@.
Ext.require("MyApp.widget.MyWidget");
describe("MyApp.widget.MyWidget", function() {
var widget;
beforeEach(function() {
widget = Ext.create("MyApp.widget.MyWidget", {
renderTo: "test"
value: "Some Initial Value",
});
});
afterEach(function() {
Ext.destroy(widget);
});
it("displays the initial value", function() {
expect($('#test .display').text()).toEqual("Some Initial Value");
});
});
You might have noted that I am using “jQuery”:http://jquery.com in the example. If you are not using jQuery in your application proper, I highly recommend including it in your @SpecRunner.html@ so you have access to it in your tests. Even if it is just to get the @text()@ function I used in the example, it will be worth your while. It definitely beats having to copy/paste “helper methods from the Sencha Forums”:http://www.sencha.com/forum/showthread.php?82225-JQuery-val-text-equivalent all of the time.
Also consider bringing in the “jasmine-jquery”:https://github.com/velesin/jasmine-jquery extension. It provides a bunch of really useful custom matchers.
Here are gists of the full “SpecRunner.html”:https://gist.github.com/3909104, “MyWidgetSpec.js”:https://gist.github.com/3909107, and “MyWidget.js”:https://gist.github.com/3915497 files.
And what exactly are we testing here? That our component can be instantiated, and a span element contains some text? That’s simplistic and unhelpful. What about real world scenarios: grids trees windows, forms,tabpanels, layouts…
What exactly does a unit test verify there? Other than controller logic I doubt there is much use of unit testing components. These need to be tested together as an application – ala functional test.
Zorg –
This was intentionally a very simplistic example. The intent of the post was to show how I am using Jasmine and Ext to unit test individual classes. Being able to focus on an individual “unit” of code like this is a must if you are doing TDD.
You mentioned that you doubt there is much use of unit testing components. If you are referring to testing out-of-the-box Ext components by themselves, then yes that doesn’t make much sense. But if you write a custom component that uses its own template and fires events based on user interactions, then there can be a great deal of benefit from writing unit tests for an individual component.
And there are always non-UI related functions like those that manipulate strings or crunch numbers. Those always benefit from being driven by unit testing.
I was trying to keep it simple in this post, but perhaps a future post could give some examples of testing something more complicated.
Thanks for the feedback!