Using Jasmine to Test an ExtJS Application

Ah, JavaScript. Its dynamic nature offers some very cool capabilities, but this comes at a cost. The lack of compile-time error checking that you might be used to from Flex or Java development means that tests take on a crucially important role. Testing is important regardless of the language you use, since it underlies the entire concepts of refactoring and iterative development. As Hamlet D’Arcy said, without test coverage “you’re not refactoring; you’re just changing shit.”

This is even more true with a language like JavaScript, where runtime errors are the only kind of errors there are. Luckily, there’s a tool called Jasmine that can help us test JavaScript code. I’d like to go over an example of using Jasmine to test an ExtJS and DeftJS application.

Setting Up

Installing Jasmine is just a matter of downloading the latest Jasmine zip file, copying the library and CSS file into your application, and modifying the included SpecRunner.html file to include your source code and spec files. I’ve pushed the entire example that I’m about to discuss to our Github repository, in case you want to follow along or try things out. In particular, you may want to take a look at my customized SpecRunner.html. It’s a bit long and my changes are not really relevant to the examples I’m going to cover, so I won’t take up space by including the source code here. The point is that the setup for Jasmine is very easy, and you can use the vanilla SpecRunner they include if you don’t want to bother with more extensive customizations.

The one thing I will mention is that I’ll be using a slightly modified version of the ExtJS application configuration file from that of the live application. One reason for this is that I need to kick off the Jasmine spec runner once ExtJS is ready to go. The other reason is that I often will configure my tests to use mock data (such as static .json files), while the live application would probably be using real server URLs for loading data. My app_jasmine.coffee file looks like:

A Basic Initial Spec

To start with, I’d just like to confirm that the application actually started up correctly and that it’s set up as I expect it to be. This BasicTest spec confirms a few high-level things about my application: is ExtJS 4 set up, is my application set up, and are my DeftJS injections set up?

Jasmine is a BDD (Behavior-Driven Development) testing framework. As such, it uses “expectations” instead of the assertions you’d see in a unit testing framework like JUnit. I can see what BDD is trying to get at (make the actual tests read more like requirement statements, and push people to define the spec first and then write the tests), but honestly I don’t see it being fundamentally different from “test-driven development”. Maybe I’m just new to it, or maybe it’s just because I use pretty much the same approach in my unit and integration tests. But that’s a digression.

However you slice it, BDD expectations work pretty much the same way that assertions do. So as you can see above, I’m just confirming, at a high level, that the application is set up the way I think it should be set up.

A More Complex Spec

OK, so great. The app seems to be set up correctly. Let’s get to something with a bit more meat. The application has a top-level tab panel as it’s main view, and an associated DeftJS ViewController to go along with it. Just so you have a visual reference, here’s what the application looks like while running:

For tests involving the tab panel and its view controller, I’ll need to do some set up and clean up for each spec that runs. Jasmine lets us do this using beforeEach() and afterEach() functions:

With the setup and cleanup for the rest of the tests out of the way, I’ll start by confirming that the view and view controller are being created correctly:

Now I can move on to testing some actual behavior. One of the cool things about DeftJS ViewControllers is that they allow the view components themselves to be pretty “dumb”. The important behavior should be handled by the ViewController. In this case, I’ve got a simple method in my MainController class that will change the title on one of the tab panels:

So I’ll create a spec that makes sure this title-changing behavior works correctly:

You can see that it’s quite simple to test the behavior of ViewControllers with this kind of approach. Since a lot of code for an ExtJS application will be view-related, this takes care of a large category of testing. But what about non-view-related behavior? And what about things that trigger asynchronous activity, which is commonplace in HTML RIAs?

Asynchronous Specs

For example, I have a CompanyStore in my application. The store acts as a backing collection for a data grid of companies, and it loads this data asynchronously from the server. I also have a simple method in CompanyStore that will filter the loaded collection of Company objects based their “industry” property. Since filtering is such a simple task in ExtJS, it’s a small method:

The trick here is that I have to wait for the JSON data to load and the store to be populated before I can test my filterIndustry() method. Jasmine allows for this with its waitsFor() and runs() helper functions:

Basically, I’m saying “wait until the store’s collection of Companies is no longer empty, and then go on and run some additional code. In this case, that means set up the filter and then check to make sure it correctly filtered out any Companies that aren’t in the Manufacturing industry.

Running the Specs

Tests aren’t any good unless you can, you know, run them. Jasmine specs are executed right in your browser; you just load up the URL for your SpecRunner.html file. When I run the specs we just created, the output looks like this:

Hooray, they pass! I can now have a beer. Bring on the Lagunitas IPA. Or better yet, the mind-blowing Lagunitas Sucks (if there is any left in existence).

Conclusion

I hope that I’ve shown how easy Jasmine makes testing ExtJS applications (or any JavaScript applications, actually). There’s even more cool stuff in Jasmine, particularly around Spys, which allow for monitoring, mocking, and intercepting method calls on JavaScript objects. I’ll dig into this topic in an upcoming blog entry. Stay tuned!

 

Brian has been developing web applications for over 14 years, primarily using Java, Groovy, .NET, ColdFusion, ExtJS, Flex, and AIR. He's worked as a consultant or employee on a wide range of projects for private companies and government agencies. Brian is a regular speaker at industry conferences, as well as a blogger and author. He has contributed to a number of community endeavors, including DeftJS, Swiz, Fusebox, ColdSpring, and several RIAForge projects.

Tagged with: , ,
Posted in HTML RIA Development, Life After Flex
8 comments on “Using Jasmine to Test an ExtJS Application
  1. Brian,

    Thank you so much for posting this! This was exactly the help I needed to get started with my Jasmine unit tests with DeftJS. I wrote a small set of tests for a simple app this afternoon, and I already feel more confident about that app. Also, as often happens with unit testing, it forced me to clean up my internal APIs a bit and allowed me to refactor without dread. If you’re ever in Chicago, I’ll buy you a beer. :-)

  2. Brian Kotek says:

    Thanks, Chad! Glad you found it helpful!

  3. yatesco says:

    Not sure if you still monitor this? but when I run this with deftjs-0.6.7, jasmine 1.3.1 and ExtJS 4.1.3 I get the following error:

    TypeError: Object [object Object] has no method ‘getController’
    at null. (http://localhost:8080/spec/MainTabPanelTest.js:19:36)
    at jasmine.Block.execute (http://localhost:8080/lib/jasmine-1.3.1/jasmine.js:1064:17)
    at jasmine.Queue.next_ (http://localhost:8080/lib/jasmine-1.3.1/jasmine.js:2096:31)
    at jasmine.Queue.start (http://localhost:8080/lib/jasmine-1.3.1/jasmine.js:2049:8)

    There are no javascript errors in Chrome console, so not sure where to go next?

    I am a *complete* newbie to DeftJS so it is almost certainly something I have done :)

    Any pointers?

  4. Conor says:

    Thanks Brian! Helpful stuff!

    • Swapnali says:

      Hi Brian

      Thank you for helpful information.

      I want to use jasmine to test my application developed in ExtJs but since I am unable to get session id in html page ,I am using runTest.aspx file to execute unit test cases.It is not able to execute those testcases,though aspx file uses html tags.

      Is it mandatory to use html page to execute unit testcases? If yes then how can I access session ID in html page?

  5. Brian Kotek says:

    Sorry, I’m not sure what you’re asking. It is not mandatory to use an HTML page to execute the tests. But since the session is managed by the server, not the browser, I have no idea what you mean. You might have better luck asking on the Jasmine Google Group.

  6. Great Stuff Brian … Grails, Extjs & Jasmine. Killer ::

    Brian are you using Spock for Grails Tests?

    More Content Dammit!

  7. Brian Kotek says:

    Hah, I agree…I need to post more, been slacking.

    I’ve used Spock a bit but nothing major yet.