问题是由于一些内存泄漏,它们不能一次执行。在运行它们时,无论何时使用什么浏览器,在某些时候,浏览器崩溃并断开连接,内存将建立起来。现在我所了解的最好的解决方法是在社区中使用的,这个问题是在多次运行中分割测试,最后通过合并单次运行的结果来获得正确的覆盖。
当我第一次遇到这个问题,我有大约1000个测试。在尝试使用所有可用的浏览器进行运行后,我已经将测试分割成多个运行,但是事实证明,这不是很好的解决方案。现在测试在14个单独的运行中并行运行,以减少完成时间,而且仍然不能永久地解决问题,但是由于资源限制(RAM,cpu)和烦人的时间消耗而延迟测试。
有人可以认为我的代码中有内存泄漏,我无法保证,即使我在浏览器中运行应用程序时没有任何问题。这就是为什么我创建了一个突出显示这个问题的示例项目。
为了再现这个问题,我正在创建一个角度service,这是一个沉重的内存消耗如下所示:
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; }
};
});
之后,我有一个简单的directive,它使用这个服务来初始化许多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());
}
};
});
最后,我正在动态地注册1000个测试套件,其中test definition是针对“0700指南”中建议的btw指令。
// define multiple suits with the same deFinition just for showcase
for (var i = 0; i < 1000; i += 1) {
describe('heavyLoad directive #' + i,testDeFinition);
}
要尝试这个例子,刚刚从GitHub结帐项目,然后运行业务开始运行:
$ npm install $ bower install
我期待着找到问题所在,最终解决问题。
干杯
添加后,测试次数不再重要,因为内存消耗是稳定的,测试可以在任何浏览器中运行。
我添加了以前的测试定义here的修改,显示了成功执行3000个二进制登录测试的解决方案。
以下是测试的样子:
describe('testSuite',function () {
var suite = {};
beforeEach(module('app'));
beforeEach(inject(function ($rootScope,$compile,heavyLoad) {
suite.$rootScope = $rootScope;
suite.$compile = $compile;
suite.heavyLoad = heavyLoad;
suite.$scope = $rootScope.$new();
spyOn(suite.heavyLoad,'getHeavyString').and.callThrough();
spyOn(suite.heavyLoad,'getHeavyObject').and.callThrough();
spyOn(suite.heavyLoad,'getHeavyList').and.callThrough();
}));
// NOTE: cleanup
afterEach(function () {
// NOTE: prevents DOM elements leak
suite.element.remove();
});
afterall(function () {
// NOTE: prevents memory leaks because of JavaScript closures created for
// jasmine Syntax (beforeEach,afterEach,beforeAll,afterall,it..).
suite = null;
});
suite.compileDirective = function (template) {
suite.element = suite.$compile(template)(suite.$scope);
suite.directiveScope = suite.element.isolateScope();
suite.directiveController = suite.element.controller('heavyLoad');
};
it('should compile correctly',function () {
// given
var givenTemplate = '<div heavy-load></div>';
// when
suite.compileDirective(givenTemplate);
// then
expect(suite.directiveScope.title).tobedefined();
expect(suite.directiveScope.items).tobedefined();
expect(suite.heavyLoad.getHeavyString).toHaveBeenCalled();
expect(suite.heavyLoad.getHeavyList).toHaveBeenCalled();
});
});
有两件事需要清理:
>编译元素时使用$ compile进行测试指令
>描述函数范围内的所有变量
他们中的两个是棘手的,很难找出并考虑到。
对于我已经知道的第一个,但是直到我发现了与茉莉花在内部工作有关的第二个知识并没有多少帮助。
我已经在他们的GitHub存储库上创建了一个issue,它应该帮助找到更好的解决方案,或者至少在开发人员之间更快地传播这些信息。
我希望这个答案对许多有这个问题的人是有帮助的。在完成我所有其他测试之后,我也会写一些信息。
干杯!