2. JavaScript unit testing
AngularJS application testing tools
Karma
Jasmine
Angular Mock
What to test
Example
3. JavaScript testing problems
◦ Mixed JS/DOM
◦ Mixed backend calls into JS functions
AngularJS tries to fight it
◦ DOM manipulations only in directives
◦ Business logic in services
◦ Flow of application in controllers
◦ . . .
5. Test runner
◦ launches HTTP server
◦ loads needed files
◦ runs test
All major browsers supported
Available for testing on continuous integration server
Configuration driven
npm install karma -g
6. Assertion library
Karma supports it via plugin
(Custom) Matchers
Setup and Teardown (beforeEach, afterEach)
Spies
describe("One testing suite", function() {
it("contains spec with an expectation", function() {
var javaCroAtendees = 12;
expect(javaCroAtendees).toBe(12, "number of javaCroAtendees
should be 12”);
});
npm install karma-jasmine -g
13. Application for displaying JavaCro atendees and filtering them
by age
14. E2E tests
How to make testing/developing more standard/automated?
◦ Use Yeoman for scaffolding your app structure
◦ Use Grunt for building, deploying and automated testing
yo angular
grunt serve
16. Use Karma as test runner
Write your tests in Jasmine
Integrate Karma on continuous integration server and
TEST, TEST, TEST, TEST… you’ll be happier later
no unit to testdon’t know which js file does what and what to expect from itStandardsMVCDOM manipulation only in directivesMaintainable and easy to test codeAngular philosophy encourages developers to create their own directives, turning the HTML into aDSL suited to building their kind of app. The result significantly reduces the amount and complexity of JavaScript needed to build web applications.The Angular philosophy is that UI is best described in declarative form (HTML), and that behavior is best described in imperative form (JavaScript) and that the two should never meet.
A test suite begins with a call to the global Jasmine functiondescribe with two parameters: a string and a function. The string is a name or title for a spec suite – usually what is being tested. The function is a block of code that implements the suite.Specs are defined by calling the global Jasmine function it, which, like describe takes a string and a function. The string is the title of the spec and the function is the spec, or test. A spec contains one or more expectations that test the state of the code. An expectation in Jasmine is an assertion that is either true or false. A spec with all true expectations is a passing spec. A spec with one or more false expectations is a failing spec.Each matcher implements a boolean comparison between the actual value and the expected value. It is responsible for reporting to Jasmine if the expectation is true or false. Jasmine will then pass or fail the spec.
a) Original service b) Mocked service$exceptionHandler –Any uncaught exception in angular expressions is delegated to this service. The default implementation simply delegates to $log.error which logs it into the browser console.This service is overridden by mock $exceptionHandler which aids in testing.$log –Simple service for logging. Default implementation safely writes the message into the browser's console (if present).Mock implementation of $log that gathers all logged messages in arrays (one array per logging level). These arrays are exposed as logs property of each of the level-specific log function, e.g. for level error the array is exposed as $log.error.logs.$interval – Angular'swrapper for window.setInterval. The fn function is executed every delay milliseconds.In tests you can use $interval.flush(millis) to move forward by millis milliseconds and trigger any functions scheduled to run in that time.$timeout –Angular's wrapper for window.setTimeout. The fn function is wrapped into a try/catch block and delegates any exceptions to $exceptionHandler serviceIn tests you can use $timeout.flush() to synchronously flush the queue of deferred functions.$httpBackend – Fake HTTP backend implementation suitable for unit testing applications that use the $http service.During unit testing, we want our unit tests to run quickly and have no external dependencies so we don’t want to send XHR or JSONPrequests to a real server. All we really need is to verify whether a certain request has been sent or not, or alternatively just let the application make requests, respond with pre-trained responses and assert that the end result is what we expect it to be.
If you don’t mock $httpBackend karma will throw exception about unexpected request
Yeoman – your tests always in same (standard place)Grunt – it will deploy your application in production without all unnecessary testsBower – you don’t need dependencies on your integration server (your tests are not using them)