Вы находитесь на странице: 1из 6

by Antoni

Thursday, March 17, 2016

JS Testing Cheatsheet
Protactor (E2E)

- Install locally (project scope):


npm install protractor --save-dev
to test if protractor working (in the project directory):
./node_modules/protractor/bin/protractor --version
should return protactor version.

then do this step (quiet important):


./node_modules/protractor/bin/webdriver-manager update
this do two thing: installing selenium standalone and chromedriver in
./node_modules/protractor/selenium/ project path.
NB: protractor automatically install jamine for you (because it depend on jasmine)

- Configuration:
To test if installation work, protractor provide us with default config [conf.js] file that can run test without have to run selenium
server. it is in ./node_modules/protractor/example. To run it go to example directory then run:
../bin/protractor.js conf.js
protractor need server to run (can be express, apache etc.). For testing or learning purpose we can use node http-server, to
install it:
npm install http-server -g
to run it:
http-server -p 8080
Important config: (for starter you only need specs [it will run just ok]), but it nice to have baseUrl, capabilities, framework

- Syntax:
Pointing browser to an url: browser.get(/)
Get current url of browser: (will return a promise) browser.getCurrentUrl().then(function(url) {});
Tell Browser to Sleep: browser.driver.sleep(500)
Element finder (single): element(locator)
Element finder (multiple/array): element.all(locator)
Selecting by CSS selector: element(by.css(.abc)), also have a short version like this $(.abc)
Selecting by CSS selector (Multiple): element.all(by.css(.abc)),
also have a short version like this $$(.abc)

Selecting by angular model: element(by.model(signin.email)


Selecting by ButtonText: element(by.buttonText(submit))
Selecting by LinkText: element(by.linkText(link))
Selecting by Angular Repeater (single):
var comment = element(by.repeater('comment in comments').row(0))

Selecting by Angular Repeater (Multiple):


element.all(by.repeater(comment in comments).then(function(comments){})
if you want to count the element that repeated, use this:
1

by Antoni

Thursday, March 17, 2016


element.all(by.repeater(comment in comments)).count()

Selecting by binding:
element(by.binding(comment.like))

Sending Keys to Input element (typing): inputElement.sendKeys(a comment)


Clear Text from input element: inputElement.clear()
Click on button or link: clickableElement.click()
Click on select option element: $(select').$('[value="ID"]').click();
for Angular Material: you need to find the select and click it first, then set browser to sleep, than you can find the obtion by
repeater like this.
element(by.model(new_business.type)).click();
browser.driver.sleep(500);
element.all(by.repeater('type in new_business.business_area').row(1)).click();

Getting text from element: element.getText()


Get Value of Element by Attribute: use this if you want to get text for input element
inputElement.getAttribute(value)

Get selected option from select box: $(select').$('option:checked').getText()


for angular material: you can use aria-checked to check the checkbox status, like this:
checkboxElement.getAttribute(aria-checked)

Ignore Sync event:

(it will return a string)

browser.ignoreSynchronization = true;

careful when using this command, use browser.sleep(), to manage the timming.

NB: important url: https://angular.github.io/protractor/#/api (for complete protractor api)


TIps: You need to do browser.get() at lease one time to home page or put it in beforeEach to make sure the test have page to
test, if not there will be an error say angular missing or not load or something else.

Karma (Unit)

- Install locally:
npm install karma --save-dev
npm install karma-jasmine karma-chrome-launcher --save-dev

- To run it:
./node_module/karma/bin/karma start

- Tired with all the browser popup, we can use phantomjs:


npm install phantomjs-prebuilt --save-dev
npm install karma-phantomjs-launcher --save-dev
then put this on karma configuration:
browsers: [PhantomJS]

- Need to Install for Angular Testing:


angular mock: bower

install angular-mocks --save-dev

- For karma configuration, need to include angular and angular-mocks path to the files:
2

by Antoni

Thursday, March 17, 2016

files: [
'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'spec/unit/**/*.js'
],

- Jasmine Syntax for Testing Angular App:


Scope init using angular-mocks inject function:
describe("description", function () {
var scope = {};
beforeEach(function () {
module('anyModule');
inject(function($controller) {
$controller('anyController', {$scope: scope});
});
});
});

If you want to test nested scope, better of with this:


describe("description", function () {
var parentScope = {};
var childScope = {};
beforeEach(function () {
module('anyModule');
inject(function($controller, $rootScope) {
parentScope = $rootScope.$new();
$controller('ParentController', {$scope: parentScope});
childScope = parentScope.$new();
$controller('ChildController', {$scope: childScope});
});
});
});

If we are using the popular Controller As syntax, we are not testing the scope we test the controller it self:
describe("description", function () {
var ctrl = {};
beforeEach(function () {
module('anyModule');
inject(function($controller) {
ctrl = $controller(ControllerName);
});
});
});

Mocking a service locally: (let say we have service named ItemService that need to be mock)
describe("description", function () {
var ctrl = {};
beforeEach(function () {

by Antoni

Thursday, March 17, 2016


module(function($provide){
mockService = {
list: function {return [id:1, label: Mock]}
}
$provide.value(ItemService, mockService);
});
});
beforeEach(function () {
module('anyModule');
inject(function($controller) {
ctrl = $controller(ControllerName);
});
});

});

Mocking a service globaly: we need to make new angular module that will overwrite current service on testing.
mock file ( also live is testing folder):
angular.module('notesApp1Mocks', [])
.factory('ItemService', [function() {
return {
list: function() {return [{id: 1, label: 'Mock'}];}
};
}]);
than we do this on test spec:
describe('ItemCtrl With global mock', function() {
var ctrl;
beforeEach(module('notesApp1'));
beforeEach(module('notesApp1Mocks'));
beforeEach(inject(function($controller) {
ctrl = $controller('ItemCtrl');
}));

it('should load mocked out items', function() {


expect(ctrl.items).toEqual([{id: 1, label: 'Mock'}]);
});
});

Use Jasmine Spy, if we didnt want to implement an entire mocked-out service, if we just wanted to know in the case of
ItemService whether or not the list function was called, and not worry about the actual value from it.
describe('ItemCtrl with SpyReturn', function() {
beforeEach(module('notesApp1'));
var ctrl, itemService;
beforeEach(inject(function($controller, ItemService) {
spyOn(ItemService, 'list').and.returnValue([{id: 1, label: 'Mock'}]);
itemService = ItemService;
4

by Antoni

Thursday, March 17, 2016


ctrl = $controller('ItemCtrl');
}));

it('should load mocked out items', function() {


expect(itemService.list).toHaveBeenCalled();
expect(itemService.list.calls.count()).toEqual(1);
expect(ctrl.items).toEqual([{id: 1, label: 'Mock'}]);
});
});

Testing a Server Call (Integeration-Level-Testing):


describe('Server App Integration', function() {
beforeEach(module('serverApp2'));
var ctrl, mockBackend;
beforeEach(inject(function($controller, $httpBackend) {
mockBackend = $httpBackend;
mockBackend.expectGET('/api/note').respond(404, {msg: 'Not Found'});
ctrl = $controller('MainCtrl');
// At this point, a server request will have been made
}));

it('should handle error while loading items', function() {


// Initially, before the server responds,
// the items should be empty
expect(ctrl.items).toEqual([]);
// Simulate a server response
mockBackend.flush();
// No items from server, only an error
// So items should be empty still
expect(ctrl.items).toEqual([]);
// and check the error message
expect(ctrl.errorMessage).toEqual('Not Found');
});

afterEach(function() {
// Ensure that all expects set on the $httpBackend
// were actually called
5

by Antoni

Thursday, March 17, 2016


mockBackend.verifyNoOutstandingExpectation();
// Ensure that all requests to the server
// have actually responded (using flush())
mockBackend.verifyNoOutstandingRequest();
});

});

- aaa
Nb: Karma conf file not taking capital letter very well (use down case for first letter when naming the file).

Subject

- xx

Вам также может понравиться