【问题标题】:Karma+Jasmine test for a Angular SPA fail randomly in AfterAllAngular SPA 的 Karma+Jasmine 测试在 AfterAll 中随机失败
【发布时间】:2019-07-24 18:26:12
【问题描述】:

我们正在构建一个 Angular 单页应用程序。过去几周的一些提交导致 AfterAll 方法中出现随机测试失败,并显示以下错误消息:

AfterAll Uncaught TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. thrown

错误有时不会出现;在浏览器中查看 Karma 控制台时,任何规格都没有错误,除了这个。我很难找到错误的根源;我不确定如何为其获取正确的堆栈跟踪。我们没有定义任何 AfterAll(它必须是 Karma 运行的一些默认规范)。禁用或启用随机测试顺序不会影响随机失败。

我们使用的版本如下:

"karma": "^4.0.1",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "^1.2.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.2",
"karma-junit-reporter": "^1.2.0"

我怎样才能得到一个正确的堆栈跟踪这个错误?随机出现什么问题?

【问题讨论】:

  • 我们需要一些代码,以便我们更好地了解问题所在并更好地帮助您。如果可能的话edit 帖子并在AfterAll 方法中添加代码以及与之相关的任何其他内容。
  • 我知道这个问题已经得到解答,但我也遇到了同样的问题,看来这篇博客文章是高度相关的:blog.pragmatists.com/…

标签: angular karma-jasmine


【解决方案1】:

自版本 3 以来的 Karma 以相同的 suitedescribe() 以随机顺序运行测试。

如果不查看实际测试,就无法确定是哪个测试导致了问题。但是您描述的症状表明您的一个测试改变了您的测试所依赖的组件上的某些状态。似乎您没有 beforeEach() 来重置每个测试的主要状态。

如果您可以发布导致此问题的测试和组件,我可以帮助您查明处于变异状态而不是修复它的测试。或者,如果您愿意,可以私下与我联系。

【讨论】:

  • 问题是:我们有 160 个规范,其中 30 个被跳过,其他运行良好,然后测试完成后仍然抛出错误,所以我不知道如何找到找出要共享/匿名化的测试。有什么办法可以查出来吗?
  • 你的规格中有afterAll()吗?否则,恐怕这是测试的麻烦,并且修复它会是一项耗时的工作,也许对于更初级的开发人员来说是这样的;-)。考虑到测试的组合可能是问题所在,禁用所有并一一重新启用可能不会导致您找到问题的原因。
  • 如果您的规范中有afterAll() 方法,更可靠的选择是在beforeEach()beforeAll() 语句中添加一些日志记录。但是,如果您没有这些;可能是测试框架本身引发了错误。你用谷歌搜索过 Karma/Jasmine 的类似错误消息吗?
  • 否则,您的选择是回到本地分支,回到破坏这一切的提交之前,看看该提交中涉及了哪些测试。恐怕如果那里涉及到很多测试,您将不得不逐一进行以隔离问题。
  • 是的,我们的整个代码库中没有 afterAll()。是否可以定义我真正在寻找什么? afterAll() 是否默认检查或尝试做某事,这可能会受到测试的阻碍?
【解决方案2】:

您可以使用fdescribe/xdescribe 缩小产生此问题的规范文件的范围。然后你可以使用 fit/xit 得到有问题的测试。

P.S:您的规范文件中没有必要存在问题。有时,代码中的故障可能会导致此类错误。一旦您知道是哪个测试产生了这个错误,就会更容易发现根本问题。

【讨论】:

  • 另外,请记住,这里的错误不仅是由测试引起的,而且组合也会运行。我在升级 karma/jasmine 时遇到过这种情况,找到实际原因(状态突变)有点费时,而且我在套件中没有太多测试。
  • 我能够隔离它;它实际上是由单个测试引起的。我仍在寻找导致 AfterAll() 失败的原因。等我知道了会回复的。
  • 很高兴,我能帮上忙。请分享 CalendarDataStoreService 的详细信息,我们可能会发现真正的罪魁祸首。另外,不要忘记将我的答案标记为已接受。
【解决方案3】:

我能够通过一个接一个地隔离模块来找到错误的测试。它看起来像这样:

import { HttpClientTestingModule } from '@angular/common/http/testing';
import { Component, Input } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { DxBoxModule, DxListModule, DxToolbarModule } from 'devextreme-angular';
import { NGXLogger, NGXLoggerMock } from 'ngx-logger';
import { of } from 'rxjs';
import { CalendarDataStoreService } from '../../services/calendar-data-store.service';
import { ExampleCommunicationService } from '../../services/example-communication.service';
import { ExamplePageComponent } from './example-page.component';

@Component({selector: 'example-calendar-list', template: ''})
class ExampleCalendarListStubComponent {
  @Input() dataSource;
  @Input() selectedItem;
}

@Component({selector: 'example-toolbar', template: ''})
class ExampleToolbarStubComponent {
  @Input() selectedCalendar;
}

describe('ExamplePageComponent', () => {
  let component: ExamplePageComponent;
  let fixture: ComponentFixture<ExamplePageComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        DxBoxModule,
        RouterTestingModule,
        DxListModule,
        DxToolbarModule,
        HttpClientTestingModule
      ],
      declarations: [
        ExamplePageComponent,
        ExampleToolbarStubComponent,
        ExampleCalendarListStubComponent
      ],
      providers: [
        {
          provide: CalendarDataStoreService, useValue: {
            createDataSource: () => {},
            modified$: of(true)
          }
        },
        {provide: ExampleCommunicationService, useValue: {}},
        {provide: NGXLogger, useClass: NGXLoggerMock},
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ExamplePageComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  xit('should create', () => {
    expect(component).toBeTruthy();
  });
});

生成提供程序的行是问题:

{
              provide: CalendarDataStoreService, useValue: {
                createDataSource: () => {},
                modified$: of(true)
              }

为提供者创建的 DataSource 导致 AfterAll() 在测试运行后失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-13
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 2021-12-27
    • 2023-03-06
    相关资源
    最近更新 更多