I'm getting the following error when running the entire suite of tests:
timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
After some investigation, I found out to be a memory leak issue. Looking at some heap profiling snapshot, objects still seem to be referenced and not getting garbaged collected.
Anyone know a solution that would prevent it from happening? There's some options such as going through each one of my 1000ish specs and adding afterEach
to do some clean up, but that seems like a lot of work.
Here's a sample layout of how most of my tests look like
describe('MyClassCtrl', function() {
var $httpBackend, $rootScope, ctrl;
ctrl = $rootScope = $httpBackend = null;
beforeEach(function() {
module('myApp');
inject(function($controller, $rootScope, _$httpBackend_, $stateParams) {
var $scope;
$stateParams.id = 1;
$httpBackend = _$httpBackend_;
$scope = $rootScope.$new();
ctrl = $controller('MyClassCtrl', {
$scope: $scope
});
});
});
describe('#_getMyList', function() {
beforeEach(function() {
$httpBackend.expectGET("/my/app/url").respond({
my_list: [1, 2, 3]
});
ctrl._getMyList();
$httpBackend.flush();
});
it('does this', function() {
expect(ctrl.my_list).to.eql([1, 2, 3]);
});
});
});
Below are some profiling screenshots:
UPDATE
I was able to trigger a memory leak by simply wrapping one of my it
in a loop.
e.g.:
for (i = 0; i < 200; i++) {
it('does this', function() {
expect(ctrl.my_list).to.eql([1, 2, 3]);
});
}
In my tests, I set all objects within a container object and cleaned it up in an afterEach
(like the solution here) but no luck. Memory allocation still keep increasing on Chrome's Dev Timeline tool.
Thanks!
Not sure but this could be related to the memory leak in Mocha that has been fixed recently. Make sure to update your local mocha to
2.4.5
or newer to get the fix and try running the test.It looks like ui-router leaks memory in unit tests. I added the following code in the run block of my application:
and the memory consumption in unit tests is 7-8 times smaller (I have around 350 states).
I don't see you cleaning up your mocked http backend. I have no idea how it functions, but I would expect that all your requests and responses are being stored in memory. That would cause it to increase gradually, test by test.
If this was using Sinon I would expect that you would create a stub/spy before the tests and clean it up afterwards (or run it in a sandbox).
Try taking a heap snapshot before and after running a test and diff the snapshots to find which objects keep increasing in numbers.