角单元测试是泄漏样式

时间:2018-08-08 17:53:39

标签: angular jasmine

在我们的项目中,我们有成千上万的单元测试,并且它们变得越来越慢。我进行了调试,发现CPU时间主要花费在渲染上。

经过更多调试后,我发现在Jasmine测试页DOM中,有成千上万个<style>标签,这似乎是性能问题的核心。

我已经在空的ng new项目上尝试过。我所做的只是为AppComponent添加了一些样式:

app.component.css

.test { color: red; }

当我使用ng test运行默认的单元测试(有3个预定义的单元测试)并在Jasmine测试页面上打开chrome控制台时,结果如下-样式是其中的三遍!:

Style issue

在运行数千个测试时,由于成千上万个<style>标签,因此性能受到很大影响。

有人知道每次测试后如何进行业力/角度清理吗?

我正在使用angular 6.1.1和angular / cli 6.0.1

4 个答案:

答案 0 :(得分:3)

我认为您遇到了以下错误:https://github.com/angular/angular/issues/31834

将以下行添加到全局afterEach确实加速了测试套件的执行:

window.document.querySelectorAll("style").forEach((style: HTMLStyleElement) => style.remove());

答案 1 :(得分:0)

该组件被配置为使用ViewEncapsulation.Emulated,这意味着app.component.css文件应仅包含:host样式和其他主机选择器。

Angular将为组件注入<style>标签,并在运行时将其绑定到主机视图。销毁组件后,会删除 host 样式,但是您已经在 host 范围之外添加了其他选择器。因此,浏览器将其保留不变,因为它们未绑定到主机。

应该通过为项目定义的style.css文件包括 global 的所有 extra 样式。

另一种选择是使用ViewEncapsulation.None而不使用:host选择器。

更新:

Angular 6已添加ViewEncapsulation.ShadowDom设置。

https://w3c.github.io/webcomponents/spec/shadow/

  

该规范描述了一种将多个DOM树组合到一个层次结构中的方法,以及这些树如何在文档中彼此交互,从而使DOM更好地构成。

Angular文档提供了以下示例:

 styles: [`
    :host {
      display: block;
      border: 1px solid black;
    }
    h1 {
      color: blue;
    }
    .red {
      background-color: red;
    }
  `],

尝试改用这种封装模式。看起来它可以解决您遇到的问题。

答案 2 :(得分:0)

好的,我尝试了更野蛮的方式,看来它正在起作用。我创建了一个具有1400个相同测试的示例应用程序(它仅呈现@angular/material按钮并对其进行检查)。

运行此测试套件需要14分钟。

添加以下行之后:

afterEach(() => {
    const head = document.getElementsByTagName('head')[0];

    const styles = document.getElementsByTagName('style');


    for (let i = 0; i < styles.length; i++) {
      head.removeChild(styles[i]);
    }
});

运行它需要80秒。

在我看来,因果报应应该以某种方式处理此问题,因为我敢打赌这是很普遍的问题

答案 3 :(得分:0)

为此,我制作了一个可以使用的函数trimLeftoverStyles,可以从我的开源库s-ng-dev-utils中获得该函数。它只会删除您的组件添加的样式。如果您添加了测试套件中使用的全局样式,则将使它们孤独。如果按照建议在beforeEach中调用它,它还将使您的组件在测试结束时样式正确,以便可以正确查看它进行调试。