Unidad AngularJs que prueba pérdidas de memoria
Como ya sabrá, muchos de nosotros que tenemos una gran cantidad de pruebas de unidades escritas nos hemos encontrado con este problema no trivialmente solucionable. Tengo alrededor de 3500+ pruebas unitarias escritas en elJazmín sintaxis que sigue a AngularJsexamen de la unidad guía. Las pruebas se ejecutan conKarma corredor.
El problema es que no se pueden ejecutar de una vez debido a algunas pérdidas de memoria. Mientras se ejecutan, la memoria se acumula sin importar en qué navegador se ejecuten y, en algún momento, el navegador se bloquea y se desconecta. La mejor solución que conozco hasta ahora y que se usa en la comunidad que tiene este problema es dividir las pruebas en varias ejecuciones y, al final, obtener la cobertura correcta fusionando los resultados de las ejecuciones individuales.
Cuando me encontré con este problema por primera vez, tuve alrededor de 1000 pruebas. Después de probar con todos los navegadores disponibles para ejecutar, he dividido las pruebas en varias ejecuciones, sin embargo, resultó que esta no es una buena solución durante mucho tiempo. Ahora las pruebas se ejecutan en más de 14 ejecuciones individuales que se ejecutan en paralelo para reducir el tiempo de finalización y aún IMO, esto no puede resolver permanentemente el problema, pero lo retrasa un poco debido a la limitación de recursos (RAM, CPU) y el consumo de tiempo molesto.
Alguien puede argumentar que tengo pérdidas de memoria en mi código que no puedo garantizar a pesar de que no tengo ningún problema al ejecutar la aplicación en el navegador. Es por eso que he creado un proyecto de ejemplo que resaltará este problema.
Para reproducir este problema, estoy creando un angularServicio que es pesado en el consumo de memoria como este:
app.factory('heavyLoad', function () {
// init
var heavyList = [];
var heavyObject = {};
var heavyString = '';
// populate..
return {
getHeavyList: function () { return heavyList; },
getHeavyObject: function () { return heavyObject; },
getHeavyString: function () { return heavyString; }
};
});
Después de eso tengo un simpledirectiva que usa este servicio para inicializar muchos elementos DOM:
app.directive('heavyLoad', function (heavyLoad) {
return {
scope: {},
template: '' +
'<div>' +
' <h1>{{title}}</h1>' +
' <div ng-repeat="item in items">' +
' <div ng-repeat="propData in item">' +
' <p>{{propData}}</p>' +
' </div>' +
' </div>' +
'</div>',
link: function (scope, element) {
scope.items = heavyLoad.getHeavyList();
scope.title = heavyLoad.getHeavyString();
// add data to the element
element.data(heavyLoad.getHeavyList());
}
};
});
Y al final estoy registrando dinámicamente 1000 suites de prueba con eldefinición de prueba para la directiva que por cierto se escribe como se sugiere en el Angularexamen de la unidad guía.
// define multiple suits with the same definition just for showcase
for (var i = 0; i < 1000; i += 1) {
describe('heavyLoad directive #' + i, testDefinition);
}
Para probar el ejemplo, solo revisa el proyecto desdeGitHub y antes de correrinicio de karma correr:
$ npm install
$ bower install
Espero encontrar el problema y resolverlo finalmente.
Salud