Tomasz Szewców
describe('A suite', function() { it('contains spec with an expectation', function() { expect(true).toBe(true); }); });
// install Karma npm install karma
// install plugins npm install karma-jasmine npm install karma-phantomjs-launcher npm install karma-chrome-launcher
// run Karma ./node_modules/karma/bin/karma start / init / run // alternative npm install -g karma-cli karma start / init / run
// can be created with karma init command module.exports = function (config) { config.set({ basePath: '', frameworks: [], files: [], hostname: 'localhost', port: 9876, autoWatch: false, browsers: [], singleRun: false, }) }; // for debugging in a browser: // - set single run to true // - select other browser
http://karma-runner.github.io/0.8/config/configuration-file.html
describe('SampleCntl tests', function() { 'use strict'; var $scope; beforeEach(module('someModule')); beforeEach(inject(function($controller, $rootScope){ $scope = $rootScope.$new(); $controller('SampleCntl', {$scope: $scope}); })); describe('some suite', function() { it('some spec', function() { // given // when $scope.someFunction(); // then }); }); });
describe('SampleCntl tests', function() { 'use strict'; var cntl; beforeEach(module('someModule')); beforeEach(inject(function($controller){ cntl = $controller('SampleCntl', {}); })); describe('some suite', function() { it('some spec', function() { // given // when cntl.someFunction(); // then }); }); });
// 1. create a sample angular module angular.module('sampleModule', []); // 2. create a calculator controller with 2 functions angular.module('sampleModule').controller('CalculatorCntl', function(){ 'use strict'; this.factorial = function(n){}; this.divide = function(a, b){}; }); // 3. specify appropriate files in the karma config file // 4. implement controller's functionality using TDD
// sample controller code angular.module('someModule').controller('SomeCntl', function($location){ 'use strict'; this.goToDialog = function(path){ $location.path(path); }; }); // test code var cntl, locationMock = { path: angular.noop }; beforeEach(inject(function($controller){ // injection of mocked $location service cntl = $controller('SomeCntl', {$location: locationMock}); }));
describe('data service tests', function () { 'use strict'; var someDataService; beforeEach(module('app')); beforeEach(inject(function (_someDataService_) { someDataService = _someDataService_; })); describe('get data method', function () { it('should return data', function () { // given var data = []; // when data = someDataService.getData(); // then expect(data.length).toEqual(10); }); }); });
// sample service code angular.module('someModule').factory('serviceUnderTests', function('otherService'){ 'use strict'; var data = []; return { getData: function(){ angular.copy(otherService.getData(), data); }, getCurrent: function(){ return data; } }; }); // test code var otherServiceMock = {getData: function(){return [1,2,3]}}; var serviceUnderTests; beforeEach(function(){ module('someModule'); module(function($provide){ // injecting other service with $provide service $provide.value('otherService', otherServiceMock); ); }); beforeEach(function(_serviceUnderTests_){ serviceUnderTests = _serviceUnderTests_; });
var booksData, $httpBackend; beforeEach(inject(function (_booksData_, _$httpBackend_) { booksData = _booksData_; $httpBackend = _$httpBackend_; })); afterEach(function () { // then $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it('should load books', function () { // given var searchParams = {title: 'title', author: 'author'}, books = [], response = [ {id: 0, title: 'title1'}, {id: 1, title: 'title2'} ]; $httpBackend.expectGET('/books-management/books-list/books.json?author=author&title=title').respond(response); // when booksData.getBooks(searchParams).then(function (response) { books = response.data; }); $httpBackend.flush(); // then expect(books).toEqual(response); });
describe('testing directive', function() { 'use strict'; var $compile, $rootScope; beforeEach(module('moduleName')); beforeEach(inject(function(_$compile_, _$rootScope_){ $compile = _$compile_; $rootScope = _$rootScope_; })); it('should replace the directive with an appropriate content', function() { // given when var element = $compile('<directive-name></directive-name>')($rootScope); $rootScope.$digest(); // then expect(element.html()).toContain('expected content'); }); });
// install protractor globally with the node package manager npm install -g protractor
// download webdriver webdriver-manager update
// start selenium server webdriver-manager start
// prepare the configuration file exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', specs: ['todo-spec.js'] };
// run e2e tests protractor [name-of-config-file]
// running tests in other browsers exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', specs: ['spec.js'], capabilities: { browserName: 'firefox' } } // running tests in many browsers exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', specs: ['spec.js'], multiCapabilities: [{ browserName: 'firefox' }, { browserName: 'chrome' }] }
https://github.com/angular/protractor/blob/master/docs/referenceConf.js
// by binding element(by.binding('item.name')); // by model element(by.model('item.name')); // by css element(by.css('some-css')); // shorthand for css selectors $('my-css') // the same as element(by.css('my-css')) // by button text element(by.buttonText('buttonText')); // by tag name element(by.tagName('tag-name')); // by repeater element.all(by.repeater('repeater'));
https://angular.github.io/protractor/#/api?view=ProtractorBy
var el = element(locator); // click on the element el.click(); // send keys to the element (usually an input) el.sendKeys('my text'); // clear the text in an element (usually an input) el.clear(); // get the value of an attribute, for example, get the value of an input el.getAttribute('value');
https://angular.github.io/protractor/#/api?view=ElementFinder
// set breakpoint browser.pause();
// continue to the next step c
// enter interactive mode repl
// exit debugging ctrl + C
// 1. create a page object for tables list dialog // - page object should have nextPage and getNumOfTables function // - nextPage has to click on the next page button (use for example by.css selector) // - getNumOfTables has to retrieve number of rows (use for example by.repeater selector) // 2. use page object in a test together with signIn page object // - sign in to table management // - assert number of rows on the first page // - move to the second page // - assert number of tables on the second page