unit testing and coverage for angularjs
TRANSCRIPT
Unit Testing and Coverage for AngularJS
Sumit Khanduri
Software Consultant Knoldus Software LLP
Introduction
● Unit testing, as the name implies, is about testing individual units of code.
● "Did I think about the logic correctly?" or "Does the sort function order the list in the right order?"
● The primary goal of unit testing is to take the smallest piece of testable software in the application.
Testing AngularJS App`s
● AngularJS build around the concept of dependency injection & loose coupling to the DOM which make it testable.
● Angular comes with dependency injection built-in, which makes testing
components much easier, because you can pass in a component's dependencies and mock them as you wish.
● Components that have their dependencies injected allow them to be easily mocked on a test by test basis, without having to mess with any global variables that could accidentally affect another test.
TDD
● Karma is a JavaScript command line tool that can be used to spawn a web server which loads your application's source code and executes your tests.
● You can configure Karma to run against a number of browsers.
● Karma is a NodeJS application, and should be installed through npm.
The main goal for Karma is to bring a productive testing environment todevelopers. The environment being one where they don't have to set up
loads of configurations, but rather a place where developers can just write the code and get instant feedback from their tests. Because getting
quick feedback is what makes you productive and creative.
http://karma-runner.github.io/
Jasmine is a behavior-driven development framework for testingJavaScript code. It does not depend on any other JavaScript
frameworks. It does not require a DOM. And it has a clean, obvioussyntax so that you can easily write tests.
http://jasmine.github.io/
Unit Test Strucuture - Specs
it('should increment a variable', function () {
var foo = 0; // set up the world
foo++; // call your application code
expect(foo).toEqual(1); // passes because foo == 1
});
Unit Test Structure – Suites
Collections of specsYour test files will contain one or more suites, each with one ormore specs.
describe("User Validation", function() { it("requires a name", function() {
//spec content })
it("does not validate invalid names", function() { //spec content
})});
Unit Test Structure – expect()
expect() is the actual 'test'Takes a value, then 'matchers'
it('should increment a variable', function () { var foo = 0; // set up the world foo++; // call your application code expect(foo).toEqual(1); // passes because foo == 1
});
Mocking in Jasmine
A test is not a unit test if:
1. It talks to the database2. It communicates across the network3. It touches the file system4. It can't run correctly at the same time as any of your other unit
tests5. You have to do special things to your environment (such asediting config files) to run it.
~ Michael FeathersNeed to use mocks to simulate calls to external services, files, etcNeed to use mocks to reduce real dependencies in tests.
Mock HTTP ($httpBackend)
● Fake HTTP backend implementation suitable for unit testing applications that use the $http service.
● Example:
mockHttpBackend.expect('POST',config.serverURL+ 'admin/login',{'email':'','password':''}).respond({ data : {} });
Matchers
Mocking in Jasmine – Spies
● Easily inject mock/monitoring objects● Replaces or wraps the function it's spying on● Gives run-time statistics on the spied function● Know how many times a function has been called● Inspect return values● Inspect parameters it('should run Successfully', function() { spyOn(mockState, 'go'); mockScope.addEmployee(); expect(mockState.go).toHaveBeenCalledWith('home');});
Spies
Istanbul
Yet another JS code coverage tool that computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Supports all JS coverage use cases including unit tests, server side functional tests
https://www.npmjs.com/package/istanbul
Istanbul-Setup● Install karma-coverage
> sudo npm install -g karma-coverage
● Install istanbul
> sudo npm install istanbul
● Karma.conf.js
> Inside preprocessors json object add the path to your file for which you need coverage report. E.g., preprocessors: 'app/component/add/add.ctrl.js':'coverage',
> Inside reporters add a string named 'coverage', E.g., reporters: ['progress','coverage',].
Istanbul Report
Setup Test Environment
● Install Karma
> npm install -g karma –save-dev
● Install Jasmine
> npm install karma-jasmine jasmine-core –save-dev
● Install ngMock
> npm install angular-mocks –save-dev
● Browser
> npm install karma-chrome-launcher –save-dev
● Create two folders in your working directory
> mkdir app
> mkdir tests
Contd..● Karma.conf.js
> karma init
> Select jasmine as your testing framework
> Select browser, whichever you like
> Specify the paths to your spec files. E.g., 'app/*.js', 'test/*.js'.
> Add the location of angularjs in your karma.conf.js.
> Add the location of ngMock library in your karma.conf.js
● Optional commands
> npm install karma --save-dev
> npm install karma-jasmine karma-chrome-launcher –save-dev
> npm install -g karma-cli
> karma start
Questions ?
References
● http://www.slideshare.net/timoxley/testing-with-jasmine?next_slideshow=1
● http://www.slideshare.net/nirkaufman/angularjs-unit-testing
● http://java.ociweb.com/mark/other-presentations/AngularJS-Testing.pdf
● https://www.youtube.com/watch?v=f7lIBiLmISQ