【问题标题】:How to bootstrap angular at the start of each karma/jasmine test file?如何在每个业力/茉莉花测试文件的开头引导角度?
【发布时间】:2015-10-09 19:29:16
【问题描述】:

是否可以在每个测试文件的开头有角度引导应用程序?而不是当前的行为,即在一系列测试开始时启动应用程序,然后在所有测试文件中使用相同的实例(我们现在在大约 60 个文件中大约有 600 个测试)?

我们有 beforeEach 语句来处理清理,但这无济于事。事实上,似乎有时 beforeEach 语句会无缘无故地被完全跳过(可能与测试运行程序发生内存泄漏)。

所以我想采取的方法是让每个测试文件引导 Angular 应用程序,以便完全重置状态,而不是重用由不同测试设置状态的依赖注入(即服务)。

【问题讨论】:

    标签: javascript angularjs unit-testing karma-jasmine


    【解决方案1】:

    您无需为测试启动应用程序。这就是为什么我们有angular-mock。使用angular.module('app.module'),我们加载了测试所需的模块,该模块包含我们要测试的组件。由于angular-mock 不是内存泄漏的原因,因此可能有多种原因。内存泄漏最常见的原因之一是 jasmine 本身以及我们通常编写测试的方式。我们用于在测试中注入的依赖项的变量是在describe 范围内定义的,并且在测试完成时无法被 GC 收集。这是因为 it 块中的这些变量的引用不能被垃圾收集,因为这些变量仍然存在于测试树的其他范围内。另一个问题可能是每次测试后也应该清理的编译元素。所以你可能需要清理以下内容:

    • 使用 $compile 测试指令时的编译元素
    • 全部 描述函数范围内的变量

    你可以这样做:

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

    取自here

    这应该会显着减少内存泄漏。 您还应该查看您的模块结构和模块具有的依赖关系图,因为您可能有一些模块在某些测试中不需要,但它们无论如何都会被加载。它们可能会占用大量内存或包含内存泄漏,并且可能会给您带来额外的问题。 你也可以看看this github project

    【讨论】:

    • 我认为你在这里展示的结构非常漂亮和干净,可能是我们项目需要的。谢谢!
    • 另一个好主意是在afterEach(...) 语句中使用$scope.$destroy()scope.$destroy()。将我们的单元测试执行时间从 30 秒缩短到 6 秒!
    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 2020-03-27
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2017-05-02
    相关资源
    最近更新 更多