Performance of unit testing with AngularJS
Speaker: Dmytro Golysh
Software engineer
In our project we have optimized unit tests, and I am speaking about how
Questions at the end!!!
For whom the presentation can help
For AngularJS developers, who use to:
What can use:
Use stopwatch and system monitor
What can use:
Use chrome memory profiler to find leaks
Problems in unit tests with AngularJS
Test execution speed
Allocated memory
Which browser to choose?
Browsers for running tests:
Headless browsers for running tests:
JSDom
. . .
Speed:
Speed:
Problem with angular.mock.module
beforeEach(module('app'));
beforeEach(function() {
module('app');
});
(function() {
'use strict';
angular
.module('app')
.run(setupPos);
/*@ngInject*/
function setupPos(PosSetupService) {
PosSetupService.setup();
}
})();
(function() {
'use strict';
angular
.module('app')
.config(routeConfig);
/*@ngInject*/
function routeConfig($stateProvider) {
$stateProvider
.state('store.previousTransaction'
..............................................
Speed:
Problem with angular.mock.inject
beforeEach(function() {
module('app');
inject(function(PreviousTransactionService,
_$q_,
_whttp_,
_$timeout_,
_TransactionStore_) {
sut = PreviousTransactionService;
$q = _$q_;
whttp = _whttp_;
$timeout = _$timeout_;
TransactionStore = _TransactionStore_;
});
data = {skus: {}};
whttp.get = env.stub().returns($q.when({data: data}));
TransactionStore.update = env.stub();
});
Speed:
Problem with angular.mock.inject
Use $controller instead of inject when we are testing controller
inject(function($controller,
_$q_,
_$timeout_) {
$q = _$q_;
$timeout = _$timeout_;
sut = $controller('TransactionSuspendController', {
$scope: $scope,
SuspendedTransactionsService: SuspendedTransactionsService,
TransactionManagerService: TransactionManagerService,
DialogService: DialogService
});
});
Speed:
Problem with angular.mock.inject
Use import in ES6 or require
import PosRegisterController from './PosRegisterController';
describe('app::pos-register: PosRegisterController', () => {
/*Define variables: let sut; ...*/
beforeEach(() => {
devicesList = {
totalElements: 2,
content: []
};
$state = {
params: {},
go: env.stub()
};
PosRegisterService = {};
sut = new PosRegisterController(devicesList, $state, PosRegisterService);
});
Memory:
Memory:
How to create giant memory leaks in AngularJS
app.directive('foo', function() {
return {
link: function(scope, element, attributes) {
$document.on('click', function() {
// code here
- Register events on window, document or body
To prevent leaks you have to:
app.directive('foo', function() {
return {
link: function(scope, element, attributes) {
var listener = function() {/* code here */};
$document.on('click', listener);
return scope.$on('$destroy', function() {
return $document.off('click', listener);
});
}
};
});
Memory:
How to create giant memory leaks in AngularJS
app.directive('foo', function($rootScope) {
return {
link: function(scope, element, attributes) {
return $rootScope.$on('event', function() {
return scope.attribute = value;
});
- $rootScope listeners
To prevent leaks you have to:
app.directive('foo', function($rootScope) {
return {
link: function(scope, element, attributes) {
var unsubscribe = $rootScope.$on('event', function() {
return scope.key = value;
});
return scope.$on('$destroy', unsubscribe);
}
..................................................................
Memory:
How to create giant memory leaks in AngularJS
app.directive('clock', function() {
return {
link: function(scope, element, attributes) {
var updateTime = function() {
return element.text((new Date()).toString());
};
return setInterval(updateTime, 1000);
- Fail to clear intervals and timeouts
To prevent leaks you have to:
app.directive('clock', function() {
return {
link: function(scope, element, attributes) {
var interval, updateTime;
updateTime = function() {
return element.text((new Date()).toString());
};
interval = setInterval(updateTime, 1000);
return scope.$on('$destroy', function() {
return clearInterval(interval);
});
Memory:
How to create giant memory leaks in AngularJS
console.log(scope)
- Output structured objects with console.log
var myScope = scope.$new() /* need remove by using myScope.$destroy(); */
- Fail to clean up scopes you created yourself
var observer = function() { /* observe expression */ };
var unsubscribe = $rootScope.$watch(observer, function(newValue, oldValue) {
/* code to run if the expression changes */
});
/* later, when you no longer need the watch */
unsubscribe();
- Fail to clean up watches on $rootScope
Conclusions. Advices
- Try to exclude config and run blocks
- Use import in ES6 instead of inject
- Avoid memory leaks in AngularJS
- karma-phantomjs-launcher
Bonus:
v1.0.0 use PhantomJS 2.1.1 released 20 days ago
Questions
Performance of unit testing Angular JS
By Dmytro Golysh
Performance of unit testing Angular JS
- 639