Angular 角度单元测试是一种泄漏类型

Angular 角度单元测试是一种泄漏类型,angular,jasmine,Angular,Jasmine,在我们的项目中,我们有数千个单元测试,它们变得越来越慢。我对它进行了调试,发现CPU时间主要花在渲染上 在进一步调试之后,我发现在Jasmine测试页面DOM中有数千个标记,这似乎是性能问题的核心 我已经在空的ng new项目上试用过了。我所做的只是向AppComponent添加一些样式: app.component.css: .test{ 颜色:红色; } 当我使用ng test运行默认单元测试(有3个预定义)并打开Jasmine测试页面上的chrome控制台时,结果如下-样式有三次!:

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

在进一步调试之后,我发现在Jasmine测试页面DOM中有数千个
标记,这似乎是性能问题的核心

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

app.component.css

.test{
颜色:红色;
}

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

在运行数千个测试时,由于数千个
标记,性能受到很大影响

有人知道如何在每次测试后进行因果报应/角度清理吗


我使用的是angular 6.1.1和angular/cli 6.0.1

组件被配置为使用
视图封装。仿真的
,这意味着
app.component.css
文件应该只包含
:host
样式和其他主机选择器

Angular将为组件注入
标记,并在运行时将其绑定到主机视图。当组件被销毁时,主体样式将被删除,但您在主体范围之外包含了额外的选择器。因此,浏览器将这些内容保持原样,因为它们未绑定到主机

任何额外的全局样式都应通过为项目定义的
style.css
文件包含

另一种方法是使用
视图封装。无
且不使用
:主机
选择器

更新:

Angular 6添加了
视图封装.ShadowDom
设置

本规范描述了一种将多个DOM树组合成一个层次结构的方法,以及这些树在文档中如何相互作用,从而实现更好的DOM组合

角度文档提供了以下示例:

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

尝试改用此封装模式。看起来它解决了您遇到的问题。

好吧,我已经尝试了更残酷的方法,它似乎起了作用。我已经创建了一个包含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]);
    }
});
每次(()=>{ const head=document.getElementsByTagName('head')[0]; const styles=document.getElementsByTagName('style'); for(设i=0;i 运行它需要80秒


在我看来,因果报应应该以某种方式处理这个问题,因为我打赌这是一个非常常见的问题

我认为您遇到了以下错误:

在全局afterEach中添加以下行确实加快了测试套件的执行速度:

window.document.queryselectoral(“style”).forEach((style:HTMLStyleElement)=>style.remove());

我为此制作了一个函数,您可以使用它调用它,您可以从我的开源库中获得它。它只会删除组件添加的样式;如果您添加了在测试套件中使用的全局样式,那么就不会使用它们。如果您按照建议在每次之前调用它,它还将在测试结束时保持组件的正确样式,以便您可以正确地查看它以进行调试。

什么类型的视图封装是
AppComponent
?默认类型,例如,
视图封装。模拟的
如果我没有弄错,我不确定我是否正确理解您。当我将样式表更改为:
:host{color:red}
时,结果完全相同,样式不会从DOM中删除。对于
视图封装.ShadowDom
,如果没有任何更改,那么这在所有浏览器中都不受支持,对吗?我刚刚尝试了ShadowDom封装。是的,它确实解决了单元测试的问题,但应用程序在非chrome浏览器中停止工作(试用Edge)。我也尝试了
Viewencapsulation。没有
,但它的结果与仿真Doubt相同:是在破坏每个测试用例后删除样式,还是我们可以利用
毕竟()
要在整个测试套件完成执行后删除它们吗?应该在每次完成后删除,因为每个测试用例都在将样式添加到html中