Basic jQuery testing with Jasmine Part 1
I have had JavaScript testing on my radar for a good few months, and in the past few months I’ve made it a big proirity to learn. So after rewriting my blog system to give me the kick up the backside, the next on my list was JavaScript Unit testing.
So for the past couple of months in my spare time I have been playing around with the JavaScript testing framework. I am going run through setting up Jasmine and jasmine-jquery and also how I tested one of my simplier plug-ins. The plug-in I am going to use in this article is a simple jQuery tab’s plug-in named fluabs. It’s available on github along with all the test’s which are not all covered in this article
What is Jasmine?
Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.
Jasmine on Github
Why Jasmine?
I do not have a huge big pro’s and con’s of why I choose Jasmine. I was doing some research in the different JavaScript testing frameworks, and Jasmine seemed to come up alot, along with QUnit and Mocha. I tried Jasmine, then had a play with QUnint. I never actually tried Mocha as it just did not sit right with me for some reason.
After playing a little with Jasmine and QUnit, and hitting a couple of little issue’s with QUnit I just decided to stick with Jasmine, rather then fully evaluate them both and make a proper decision. So that’s how I chose Jasmine, probably not the best but I am getting on really well with Jasmine, at first the whole testing thing was really alien to me and it was Jasmine that actually made it click, or that fact I stuck at it.
On top of Jasmine, I am also using jasmine-jquery.
jasmine-jquery provides two extensions for Jasmine JavaScript Testing Framework
1, a set of custom matchers for jQuery framework
2, an API for handling HTML fixtures in your specs
Getting Started
As I am using jasmine-jquery, you need to download jasmine, aswell as jasmine-jquery. Also, as we are testing jQuery you will need a copy of jQuery. You could use a CDN, but I have downloaded it and put it in with my test’s so I have the correct version that I have used to develop the plug-in with. This would then allow us to re-run our tests when a new version of jQuery is released to check if our plug-in is compatable with it.
My folder structure for my plug-in is, which I use for all jQuery/JavaScript plug-in’s/code:
- demo – contains a HTML file that demo’s my plug-in pulling the JS from the other folders
- dist – contains a production ready minified version of the plug-in
- src – this contains the unminfied development plug-in code
- tests – this contains Jasmine/ jasmine-jquery, and my test stuff
Getting the files
- First thing to do is download the latest standalone jasmine package from their github downloads page,
- Extract and place somewhere. I put everything under a folder named tests within my plugin folder that I going be testing,
- Download jasmine-jquery from their github downloads page – jasmine-jquery is a single file, this needs to be put in the lib folder that is in side the test folder we created in step 2,
- Put a copy of the version of jQuery you need for your plug-in in the lib folder to
Adding jasmine-jquery and jquery
You now have jasmine and jasmine-jquery downloaded, you will now need to update the SpecRunner.html file to work with jasmine-jquery. It’s not too difficult just a case of adding a couple of script tags
You need to add the jasmine-jquery.js file on the line after the jasmine-html.js file like so:
<script type='text/javascript' src='lib/jasmine-jquery.js'></script>
And as we are testing jQuery you need to add jQuery to you page, which you will be familiar with. You add this on the line below jasmine-jquery.js like so:
<script type='text/javascript' src='lib/jquery.js'></script>
Now we have the testing lib’s all set up we need to add our test specs and jQuery plug-in so we can run test’s against it.
Adding plug-in and Spec
You need to add your jQuery plug-in code just like you would if you where putting it on any site, using the script tag. Rather than duplicate copies of the plug-in I reference the plug-in from the src folder as this is the development code and this code we want to test against. So I add the plug-in to the SpecRunner.html like:
<script type='text/javascript' src='../src/fluabs.js'></script>
We also need to create a Spec file that will contain our tests, I called it SpecFluabs.js and saved it in the spec folder, and referenced it in the SpecRunner.html file like:
<script type='text/javascript' src='spec/SpecFluabs.js'></script>
You will notice in the SpecRunner.html file there is the following code:
<!-- include source files here... --> <script type='text/javascript' src='src/Player.js'></script> <script type='text/javascript' src='src/Song.js'></script> <!-- include spec files here... --> <script type='text/javascript' src='spec/SpecHelper.js'></script> <script type='text/javascript' src='spec/PlayerSpec.js'></script>
This is the default spec code and JavaScript code that is tested against, I remove the script tags and replace them with reference to my JavaScript and Spec files.
Testing the plug-in
As I had already written the plug-in, I’ve just added tests to prove it’s working. We could then use the testing framework set up to do test-driven development if I or someone else would like to contribute to the plug-in.
Now we got the test folder all set up we can start writing some test’s to check the plug-in does what it’s supposed to do.
The basics of Jasmine. Jasmine uses’ Suites to describe your tests, Specs which contain one or more expections, Expections which take a value, which your matcher is responsilbe for checking if your expection is true or false.
For complete documentation see the jasmine documentation
Tests
Right we have everything set up, lets write some tests. Ah one more thing, as we are testing a jQuery plugin we need to load the HTML required for the plug-in and bind the plug-in to it to simulate it being in the DOM. With jasmine-jquery you get the ability to have HTML fixtures, which is way you can load HTML content that is needed for your tests.
For this plug-in we need a fixture that contains the sample HTML needed for the plug-in. I put my fixtures in a folder named fixtures within the tests/spec/. You need to update jasmine-jquery.js to reflect where you have put your fixture folder, this is on line 76 ofjasmine-jquery.js
So we create a file named fluabs.html inside of the fixtures folder and add the HTML needed for our plug-in.
We now need to make this fixture avaiable to our test’s, which you do using loadFixtures() in your test spec.
For testing this plug-in we want to reset the state of our test code and plug-in, so that it’s as if the page has just loaded and nothing has happened. We do this using a beforeEach(). So we want to load our fixture inside of the beforeEach() function and initaite the plugin. We do this like:
var fixture; beforeEach(function () { loadFixtures('fluabs.html'); fixture = $('#tabs'); fixture.fluabs();
});
We have defined a variable name fixture which we can use later on to test againt in our Specs. We then use the beforeEach() to load our fixture and then to initaite our plug-in. As we have told the plug-in and HTML to load beforeEach(), it will load before each spec in the describe, so we want to reset the code by using afterEach(). So we set our Suite up and theafterEach() function:
afterEach(function () { $('#tabs').remove(); });
Now we have the plug-in and the HTML needed for our plug-in getting loaded beforeEach test and our plugin is removed after each, we can start writing some tests.
We use the describe() function to set up a suite which will contain multiple specs and a nested suite with more specs.
describe('fluabs', function() { });
Now we need to add our first spec, so the first test we need to do is to check if the plug-in has been defined and we do this like:
it('to be defined', function() { expect( fixture ).toBeDefined(); });
Open SpecRunner.html in your browser (use FireFox or Safari, or read the documentation on how to use Chrome), and this should pass, if not we have an issue!
Our second spec would be to check that the first content area is shown and the others are not, as we are using the plug-in with default option’s we know this is what should happen so we set our spec, expections and matchers to check all this:
it('tab one to be shown and others to be hidden', function() { expect( $('[data-tab='#one']') ).toBe( ':visible' ); expect( $('[data-tab='#two']') ).not.toBe( ':visible' ); expect( $('[data-tab='#three']') ).not.toBe( ':visible' ); });
As we are using jasmine-jquery and jQuery we can use jQuery selectors in our expect.
Refresh your SpecRunner.html (sometimes you may need to clear your cache) and see all green.
So we have some basic test’s set up, for our plug-in, in another article I will go into more depth on testing with spies to test click events and make sure everything works.