How to bootstrap angular at the start of each karma/jasmine test file?

ngDeveloper

Is it possible to have angular bootstrap the app at the beginning of each test file? Instead of the current behavior, which has the app bootstrap at the beginning of the series of tests, and then the same instance is used throughout all the test files (we have about 600 tests throughout ~60 files right now)?

We have beforeEach statements to handle clean-up and that doesn't help. In fact, seems sometimes the beforeEach statements are altogether skipped for no apparent reason (possible memory leak with test runner).

So the route I would like to take this is to have each test file bootstrap the angular app, so that the state is completely reset, instead of reusing dependency injection (ie. services) that had state set by a different test.

peso_junior

You don't need to bootstrap the app for the tests. That's why we have angular-mock. With angular.module('app.module') we load the module we need for our test and that module contains the component we want to test. Since angular-mock is not the cause for the memory leaks, there can be several reasons for them. One of the most common reasons for memory leaks is jasmine itself and the way we usually write the tests. The variables we use for the dependencies we inject in our test and are defined on the describe scope and cannot be collected by the GC when the tests finish. This is because there are references of those variables in the it blocks that cannot be garbage collected because the variables still live in some other scope of the tests tree. Another problem can be the compiled elements that should also be cleaned up after each test. So you probably need to clean-up the following things:

  • compiled element when using $compile for testing directives
  • all variables in the describe functions scope

You can do something like this:

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();
    });

});

Taken from here.

This should reduce your memory leaks significantly. You should also take a look at your module structure and the dependency graph your modules have, cause you might have some modules that are not needed for some tests but they are loaded anyway. They can be heavy on memory or contain memory leaks in them and can make you additional problems. You can also take a look at this github project.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Parameterized test for each file

Display TimeStamp (Start Time/End Time) for each of the Test Scenario in Cucumber Report (.html/.json) file

How to store logs in a separate file for each test in pytest

How to handle bootstrap-daterangepicker in angular component unit test?

Do not know how to test angular.bootstrap wrapper

How to write a bootstrap action to download a file to each node in EMR?

JMeter: CSV Data Set Config "Lines are read at the start of each test iteration." - how exactly should it work?

How to read config file before Angular 2 app start?

How to access style present in .css file in angular unit test

How do I unit test downloading a file using Jasmine (Angular)?

How to test if a substring from each line of File1 exists in File2

Angular materials - how start?

Angular bootstrap datepicker start date function

how to delete file that start with "-"

How to detect each JavaDoc block start-and-end line in a source-code file?

How to output my data into a new csv file each time I start my C++ program?

How to stop re-logins in after each test (Cypress-Angular)?

How to have Bootstrap's scss variables globally in Angular without importing theme every time in each component?

Spring loads context for each unit test file

Protractor test a bootstrap modal - not angular page - timeout

unit test angular bootstrap modal service

Angular How to test @HostListener

How do I run a Visual Studio unit test for each file in a directory?

How can I define test fixtures for jest.each in a separate file?

How to do jasmine unit test case for angular 6 bootstrap 4 modal

Remove the file extension of each file angular 6

How to test dockerignore file?

tslint to check each file if there is specific string present at the start of the file

How to start for-each loop from the beginning?