Unit testing is an important part of the software development process as it allows a developer to spell out their intent by creating tests containing assertions that prove it. In a dynamic language like JavaScript it's even more so important to do so for the project's stability, quality and longer term maintainability. JavaScript's great flexibility and power to quickly create software also presents a lot of opportunity to create problems if checks and balances are not in place to maintain order. In the following blog series I'll talk a bit about how to create unit tests for applications written with Ionic, a mobile hybrid framework based on Angular.js and Cordova which are JavaScript based technologies.
The Components
Ionic uses Gulp, a JavaScript based streaming build system, out of the box so we'll also leverage Gulp to create a task for running unit tests and seeing their results. Gulp tasks are generally composed by using an existing Gulp module, as thousands exist to perform almost any task you can think of, and some custom code to configure those modules for your project. I'll create a task using Karma, a JavaScript test runner, that will load our test files and execute them in the headless browser called PhantomJS and then display the results on the command line. Finally, we'll use the Jasmine test framework along with Angular mocks in order to create suites of tests containing assertions about our code that we expect in order for it to run properly. In our ionic project directory the following npm and bower commands will install the required packages:
npm install karma --save-dev
npm install karma-jasmine --save-dev
npm install karma-phantomjs-launcher --saved-dev
npm install -g karma-cli
npm install karma-spec-reporter --save-dev
npm -g install phantomjs
bower install angular-mocks --save-dev
Initialize Karma
Karma uses a configuration file to tell it how to run tests, what source files it should include, how to display results and more. In order to create a configuration file we can use karma's command line client:
karma init
Karma guides you through it's initial setup on the command line with a series of questions, for this example I specified:
- Testing framework: Jasmine
- Require.js: no
- Capture any browsers automatically: PhantomJS
- Source location: www/js/**/*.spec.js
- (Default for the rest)
Detailed Test Output on the Console
By default Karma is configured to use the 'progress' reporter which will show an ascii progress bar in the console output with a summary of the test results. In order to see a bit more detail about what tests are passing/failing change the reporter from 'progress' to 'spec' in the generated Karma config file:
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['spec'],
Gulp task to run our tests
In the gulpfile.js that is created with our Ionic project, I'll add a task to kick off Karma and run our unit tests:
var Server = require('karma').Server;
gulp.task('test', function (done) {
new Server({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, done).start();
});
Run Tests and See Results
Now any tests that have been created in our project can be run and have the results displayed in detail on the command line by running 'gulp test' in our project directory
$ gulp test
[22:32:38] Using gulpfile C:\Development\Blogging\ionicut\gulpfile.js
[22:32:38] Starting 'test'...
05 03 2016 22:32:38.745:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/
05 03 2016 22:32:38.757:INFO [launcher]: Starting browser PhantomJS
05 03 2016 22:32:40.488:INFO [PhantomJS 2.1.1 (Windows 8 0.0.0)]: Connected on socket /#5PSNRP-konOjgWF1AAAA with id 41621962
Dashboard controller tests
When the dashboard view is shown
✓ Should show a one time welcome message
✓ Should store that the message was shown in local storage
PhantomJS 2.1.1 (Windows 8 0.0.0): Executed 2 of 2 SUCCESS (0.005 secs / 0.039 secs)
TOTAL: 2 SUCCESS
[22:32:40] Finished 'test' after 2.08 s
In the next part of this blog series I'll talk a bit about Jasmine test framework concepts and how to structure tests within an Ionic project
Labels: Cordova, Ionic, Jasmine, Unit Test