Upload
raissa-ferreira
View
313
Download
0
Embed Size (px)
Citation preview
Testing Tools
● Testing Frameworks○ Jasmine
● Karma (Unit Test)● Grunt● Protractor (E2E Test)● Bower● NVM
QUnitExample 1test('test', function() {
equals( {}, {}, 'fails, these are different objects');
});
Example 2module('Module A');
test('a test',function() {});
test('an another test',
function() {});
module('Module B');
test('a test',
function() {});
test('an another test',
function() {});
JasmineExample
describe("A spec", function() {
var foo;
beforeEach(function() {
foo = 0;
foo += 1;
});
it("is just a function, so it can contain any code",function(){
expect(foo).toEqual(1);
});
});
Jasmine X QUnit
● Nested describes ● Less vulnerable to
changes, less setup
● Modules(can’t be nested)
● Massive amount of setup to cover all different paths
MochaExamplevar assert = require("assert")
describe('Array', function(){
describe('#indexOf()', function(){
it('should return -1 when the value is not present',
function(){
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
});
});
});
Jasmine X Mocha
● Runner● Nested describes● Built-in:
○ Assertion library○ Mocking library
● Runner● Nested describes● You can choose:
○ Assertion library (eg. Chai)
○ Mocking library(eg. Sinon)
● Pick syntax
Jasmine
● Behavior Driven Development testing framework for
JavaScript
● Does not depend on any other JavaScript frameworks
● Does not require a DOM
● Clean syntax
Suites● Begins with global Jasmine function describe
○ Takes two parameters:
■ string - a name or title for a spec suite, what is being
tested
■ function - Block of code that implements the suite
Jasmine
Specs● Begins with global Jasmine function it.
○ Takes two parameters:
■ string - title of the spec
■ function - the spec, or test
○ Can contains one or more expectations
■ Expectation - assertion that is either true or false
○ Passing spec - all true expectations
○ Failing spec - one or more false expectations
Jasmine
Expectations● Built with function expect
○ Takes the actual value
● Chained with a matcher function
○ Takes the expected value
Eg. expect(actualValue).toEqual(expectedValue);
Jasmine
Matchers
● Implement boolean comparison between actual and expected
value
● Responsible for reporting to Jasmine if expectation is true or
false
○ Based on this, Jasmine will pass or fail the spec
● Matcher can evaluate to a negative assertion by chaining the
call to expect with a not
Eg. expect(a).not.toBe(null);
Jasmine
Matchers
● Included Matchers
○ toBe(===), toEqual, toBeNull, toBeDefined, toBeUndefined
○ Boolean Casting - toBeFalsy, toBeTruthy
○ String/Regex - toMatch
○ Array - toContain
○ Math - toBeLessThen, toBeGreaterThan
○ Precision Math - toBeClose
○ Check if function throws exception - toThrow
Jasmine
Spies● Test double functions
● Can stub any function
● Tracks calls to it and all arguments
● Only exists in describe and it blocks it is defined
■ Will be removed after each spec
● Matchers
■ toHaveBeenCalled - if the spy was called
■ toHaveBeenCalledWith - if argument list matches any of
the recorded calls to the spy
Jasmine
JasmineAsynchronous Support
● beforeEach, it and afterEach can take optional single
argument to be called when the async work is complete
JasmineAsynchronous Support
describe("Asynchronous specs", function() { var value;
beforeEach(function(done) { setTimeout(function() { value=0;
done(); }, 1);});
it("should support async execution of test preparation and expectations", function(done) { value++; expect(value).toBeGreaterThan(0); done(); });});
ngMock● Provides support to inject and mock Angular services into unit
tests
● Extends various core ng services
○ $exceptionHandler
○ $log
○ $interval
○ $httpBackend○ $timeout
● Instalation (via Bower)
$ bower install angular-mocks --save-dev
ngMockFunctions (declared ONLY in jasmine or mocha)
● angular.mock.module○ Registers a module configuration code
○ Collects configuration information to be used when the injector
is created by inject
● angular.mock.inject○ Wraps a function into an injectable function
○ Creates new instance of $injector per test to be used for
resolving references
○ $injector is used to retrieve object instances as defined by
provider, instantiate types, invoke methods, and load modules
Unit Test (Service)
describe("Auth", function() {
beforeEach(module("app"));
var Auth, $httpBackend;
beforeEach(inject(function(_Auth_, _$httpBackend_) {
Auth = _Auth_;
$httpBackend = _$httpBackend_;
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingRequest();
});
Unit Test (Service)describe(".logout", function() {
describe("given a valid token", function() {
var Session, token = "9664bbf375";
beforeEach(inject(function(_Session_) {
Session = _Session_;
$httpBackend.
whenGET("api/auth/logout.json?token="+token).
respond(200, { invalid: true });
spyOn(Session, "clear");
}));
it("should erase user’s token", function() {
Auth.logout(token);
$httpBackend.flush();/* explicitly flush pending requests */
expect(Session.clear).toHaveBeenCalled();
});
}); });
Unit Test (Controller)describe("AuthController", function() {
beforeEach(module("app"));
var $scope, controller, $httpBackend;
beforeEach(inject(
function($controller, $injector, _$httpBackend_) {
$httpBackend = _$httpBackend_;
$scope = $injector.get("$rootScope").$new();
controller = $controller("AuthController",
{ $scope: $scope });
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingRequest();
});
Unit Test (Controller)describe(".login", function() {
var $state, httpBackend;
describe("given valid user"s credentials", function() {
beforeEach(inject(function(_$state_) {
$state = _$state_;
$httpBackend.whenPOST("api/auth/login.json").respond(200,{});
spyOn($state, "go");
$scope.login();
$httpBackend.flush();
}));
it("should go to role selection state", function() {
expect($state.go).toHaveBeenCalledWith("role_selection");
});
});
}); });
Karma● Testing Engine
○ Launches a HTTP server and generates the test
runner HTML file
■ Runs in browser
■ Can run in multiple real browsers (can also
run in a headless one - PhantomJS)
■ Show output in command line■ Developed by the AngularJS team
Karma● Instalation
# Install Karma:
$ npm install karma karma-cli --save-dev
# Install plugins that your project needs:
$ npm install karma-jasmine karma-phantomjs-launcher karma-
coverage karma-mocha-reporter --save-dev
● Configuration
# Initialize a config file:
$ node ./node_modules/karma-cli/bin/karma init [<configFile>]
Karma● Configuration file ( karma.conf.js )
module.exports = function(config) { config.set({ frameworks: ["jasmine"], files: ["src/*.js","test/*.js"], plugins: ["karma-jasmine","karma-phantomjs-launcher",
"karma-coverage","karma-mocha-reporter"], browsers: ["PhantomJS"], reporters: ["mocha","coverage"], preprocessors: {"src/*.js": "coverage"}, coverageReporter: { type : "html", dir : "coverage"}, display: "full", isVerbose: true, showColors: true, includeStackTrace: true });};
● Javascript Task Runner● Automation of repetitive tasks:
○ Minification○ Compilation○ Unit Testing
...● Instalation# install Grunt
$ npm install grunt
# install Grunt’s command line interface globally
$ npm install -g grunt-cli
Grunt
● Gruntfilegrunt.initConfig({
...
unit: {
configFile: "karma.conf.js",
singleRun: true,
browsers: ["PhantomJS"]
}
});
...
grunt.loadNpmTasks("grunt-karma");
grunt.registerTask("unit", "Run unit test",["karma"]);
Grunt Task for Karma
Protractor● Acceptance tests
● Integration Tests
● Main paths
● Takes longer to run(compared to unit testing)
● WebdriverJS (Binding for Selenium Webdriver)
● Works better with Jasmine
● Currently does not support PhantomJS
ProtractorAPI (Most Common functions)
● element Eg. element(locator)
○ isPresent
● element.all
● browser
○ waitForAngular
○ get
○ pause
○ debugger
API (Most Common functions)
● Protractor’s locators○ by
■ binding■ model■ css■ cssContainingText■ buttonText
● getText● sendKeys● clear● getAttribute
Protractor
Protractor● Example
describe("angularjs homepage", function() { it("should add one and two", function() {
browser.get("http://juliemr.github.io/protractor-demo/");element(by.model("first")).sendKeys(1);element(by.model("second")).sendKeys(2);element(by.id("gobutton")).click();expect(element(by.binding("latest")).getText()). toEqual("3"); });
});
});
ngMockE2E● Fake HTTP backend implementation suitable for end-to-end testing
○ $httpBackend● Can be used via:
● when API - when(<HTTPMETHOD>, url, params).respond
(statusCode, data)
○ shortcuts (whenGET, whenPOST,..)
● Can pass through requests to the real $httpBackend (passThrough
function)
● Flushes mocked out requests automatically
● Instalation (via Bower)
$ bower install angular-mocks --save-dev
● Instalation
# Install Protractor:
$ npm install protractor --save-dev
# Install webdriver-manager, helper tool to get an instance of a
Selenium Server running:
$ node node_modules/protractor/bin/webdriver-manager update
# Install Grunt Protractor Task
$ npm install grunt-protractor-runner --save-dev
# Install Rails Server Task
$ npm install grunt-rails-server--save-dev
Protractor
Protractor● Configuration file(protractor.conf.js):
exports.config = {
capabilities: {
"browserName": "chrome"
},
directConnect: true, /* bypass selenium webdriver */
specs: ["spec/javascripts/e2e/**/*.js"],
baseUrl: "http://local.ntp.uff.br:4000",
framework: "jasmine"
}
● Gruntfile grunt.initConfig({
... rails: { /* Backend Task */
options: {
port: 4000,
environment: "test",
keepAlive: false
},
your_target: {
}
}
...
Grunt Task for Protractor
● Gruntfileprotractor: {
options: {
configFile: "node_modules/protractor/referenceConf.js",
keepAlive: false,
noColor: false,
},
your_target: {
options: {
configFile: "protractor.conf.js",
args: {}
}
}
}
Grunt Task for Protractor
● Gruntfile ... grunt.loadNpmTasks("grunt-rails-server");
grunt.loadNpmTasks("grunt-protractor-runner");
...
grunt.registerTask("e2e", "Run e2e test",
["rails", "protractor"]);
Grunt Task for Protractor
NVM
● Instalation# Install nvm (Node Version Manager)$ curl https://raw.githubusercontent.com/creationix/nvm/v0.23.3/install.sh | bash
# To source it from your shell, this line can be added to ~/.bashrc, ~/.profile, or ~/.zshrc
$ source ~/.nvm/nvm.sh
# To install a node version
$ nvm install 0.10
# In your project folder, you can include a .nvmrc file to choose the desired node version
$ nvm use 0.10
Bower
Package Manager for Web● Instalation# Install Bower globally
$ npm install -g bower
# Interactively create a bower.json file
$ bower init
# Install a package
$ bower install <package-name>
# List all installed packages and check for new versions$ bower list
# Clean local unused packages
$ bower prune
Bower
● Configuration bower.json
{
"name": "assets",
"dependencies": {
"jquery": "latest",
"bootstrap": "latest",
"angular": "1.3.4"
...
}
.bowerrc
{
"directory": "vendor/assets/bower_components"
}
ResourcesTesting Frameworks● QUnit
http://qunitjs.com/
● Jasmine
http://jasmine.github.io/2.2/introduction.html
● Mocha
http://mochajs.org/
Assertion library● Chai
http://chaijs.com/
Mocking library● Sinon
http://sinonjs.org/
ResourcesUnit Testing
● Unit Testinghttps://docs.angularjs.org/guide/unit-testing
● Jasminehttp://jasmine.github.io/2.2/introduction.html
● ngMockhttps://docs.angularjs.org/api/ngMock
ResourcesTest Runner● Karma
http://karma-runner.github.io/
● Karma Jasmine
https://www.npmjs.com/package/karma-jasmine
● Karma PhantomJS Launcher
https://github.com/karma-runner/karma-phantomjs-launcher
● Karma Mocha Reporter
https://www.npmjs.com/package/karma-mocha-reporter
● Karma Coverage
https://github.com/karma-runner/karma-coverage
● PhantomJS
https://github.com/ariya/phantomjs
E2E Testing
● E2E Testhttps://docs.angularjs.org/guide/e2e-testing
● Protractorhttp://angular.github.io/protractor
● ngMockE2Ehttps://docs.angularjs.org/api/ngMockE2E
● HTTP Backend Proxyhttps://www.npmjs.com/package/http-backend-proxy
Resources
Automate Tasks
● Grunthttp://gruntjs.com/
● Grunt Karmahttps://github.com/karma-runner/grunt-karma
● Grunt Protractor Runnerhttps://www.npmjs.com/package/grunt-protractor-runner
Resources
Interesting Podcasts
● Adventures in Angular Podcasthttp://devchat.tv/adventures-in-angular/026-aia-testing-toolshttp://devchat.tv/adventures-in-angular/025-aia-testing-with-ward-bell
Resources