Wednesday, January 04, 2017

AngularJs Unit testing using Karma and Jasmine Frame work


Karma is a simple tool that allows you to execute JavaScript code in multiple real browsers. We can execute the command on command prompt and it display the result on prompt itself. Karma is good in advance to test our Angular js in all browsers during development and continuous integration server. Karma runs on Node.js and is available as an NPM package (for linux NVM).
==Karma Installation
# Install Karma:
$ npm install karma --save-dev
# Install plugins that your project needs:
$ npm install karma-jasmine karma-chrome-launcher --save-dev
This will install karma, karma-jasmine and karma-chrome-launcher packages into node_modules folder where we had executed above command.
# Run Karma:
$ ./node_modules/karma/bin/karma start
image1image2
Karma is not testing framework or assert library. It just help developer to to launch HTTP server and generates test runner HRML Files. For this we need to have a well defined Testing frame work. Many good frame work are available i.e. Jasmine, Mocha, QUnit etc. Here we will discuss only of Jasmine
Lets start with different aspect of Karma testing tool
1:- configuration
Karma needs to know about our project to test it and this is done with the help of configuration file.
C:\Software\karma\node_modules\.bin\karma init mySiddhu.conf.js
image3
keep this mySiddhu.conf.js in your project folder i.e.in same line where your webcontent folder exist.
2:- Create test folder and inside it put following files
adddemo.controller.test.js
angular-mocks.js
angular.min.js
Note: We need to add angular-mocks.js and angular.min.js because when we execute or js files from C:/workspace-Angular-js/TestSiddhuAngularJS/WebContent/js/adddemo.js it will give error that it did not find angular
3:- Modify our mySiddhu.conf.js as shown below
// list of files / patterns to load in the browser
files: [
'C:/workspace-Angular-js/TestSiddhuAngularJS/lib/angular.min.js',
'C:/workspace-Angular-js/TestSiddhuAngularJS/lib/angular-mocks.js',
'C:/workspace-Angular-js/TestSiddhuAngularJS/WebContent/js/*.js',
'C:/workspace-Angular-js/TestSiddhuAngularJS/test/*.js'
],
4:- Start Karma server using this created js
C:\Software\karma\node_modules\.bin\karma start mySiddhu.conf.js
or using below command
C:\Software\karma\node_modules\.bin\karma start mySiddhu.conf.js --log-level debug --single-run
If you get error Error: Cannot find module 'jasmine-core' then use below command to install jasmine-core
C:\Software\karma>npm install jasmine-core --save-dev
image4
5:- Now execute your command and see the result on the screen

image5
=============JS files
1:- mySiddhu.conf.js
// Karma configuration
// Generated on Wed Jan 04 2017 14:08:26 GMT+0530 (India Standard Time)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',

// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],

// list of files / patterns to load in the browser
files: [
'C:/workspace-Angular-js/TestSiddhuAngularJS/lib/angular.min.js',
'C:/workspace-Angular-js/TestSiddhuAngularJS/lib/angular-mocks.js',
'C:/workspace-Angular-js/TestSiddhuAngularJS/WebContent/js/*.js',
'C:/workspace-Angular-js/TestSiddhuAngularJS/test/*.js'
],

// list of files to exclude
exclude: [
],

// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},

// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],

// web server port
port: 9876,

// enable / disable colors in the output (reporters and logs)
colors: true,

// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,

// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,

// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
Note :- Make sure that you add js in sequence in conf file i.e.
'C:/workspace-Angular-js/TestSiddhuAngularJS/lib/angular.min.js',
'C:/workspace-Angular-js/TestSiddhuAngularJS/lib/angular-mocks.js',

if you try to use C:/workspace-Angular-js/TestSiddhuAngularJS/lib/a*.js instead it will give error.
2:- adddemo.controller.test.js
describe('myApp', function () {
beforeEach(module('myApp'));
var $controller;
beforeEach(inject(function(_$controller_){
$controller = _$controller_;
}));
describe('add', function () {
it('1 + 1 should equal 2', function () {
var $scope = {};
var controller = $controller('myCtrl', { $scope: $scope });
$scope.firstNumber = 5;
$scope.secondNumber = 2;
$scope.add();
expect($scope.answer).toBe(7);
}); 
});
});
3:- adddemo.js
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.add=function(firstNumber,secondNumber){
//alert('hello');
$scope.answer = parseInt($scope.firstNumber) + parseInt($scope.secondNumber);
//Now you can set a debugger here and check the data
}
});
Our Angular JS project for which we had written Karma and Jasmine unit testing.
1- HTMl File
<!--!DOCTYPE html>
<!--html>
<!--script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"><!--/script>
<!--script src="js/adddemo.js"><!--/script>
<!--body>
<!--div ng-app="myApp" ng-controller="myCtrl">
First Number: <!--input ng-model="firstNumber">
Second Number: <!--input ng-model="secondNumber">
<!--p>Answer: {{answer}}<!--/p>
<!--button name= "Add" type="button" ng-click='add(YourTextData)'>Click Me!<!--/button>
<!--/div>
<!--/body>
<!--/html>
2- adddemo.js
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.add=function(firstNumber,secondNumber){
//alert('hello');
$scope.answer = parseInt($scope.firstNumber) + parseInt($scope.secondNumber);
//Now you can set a debugger here and check the data
}
});
Folder Structure of the project in Eclipse
image6

No comments: