我们有一个中等大小的 Angular 应用程序,目前约有 700 个单元测试。
几周前,完美的测试开始出现问题。更奇怪的是:运行测试两次可能会产生不同的结果,即不同的测试可能会失败。
在控制台中,我们总是发现错误:
未捕获的类型错误:您在需要流的地方提供了“未定义”。
但堆栈跟踪没有提示错误的根源实际位于何处(请参阅本文末尾)。堆栈跟踪显示了与mergeMap
运算符,但事实证明,我们在应用程序中和测试中都没有使用此运算符。
我单步执行了所有规范文件并让它们自行运行(使用fdescribe
)。每个规格文件均顺利通过。将它们全部运行在一起会导致所描述的损坏。
当然,我的猜测是我们面临一个异步问题,因此我努力完成所有测试并将每个测试包装在异步环境中。我还检查了每个订阅在某个时刻都会被取消订阅 - 我们的应用程序就是这种情况,但对于我们的测试而言并非总是如此。
但是,错误仍然存在。
这对我们的项目来说是一个大问题。任何建议都非常受欢迎。
也许有人知道一种方法来找到导致问题的测试部分?
我们现在使用 jasmine 3.3.0、karma v3.1.4 和 Angular 7.1.3。
我们一周前对 jasmine 和 Angular 进行了更新,因为我们希望摆脱这个问题。只有一件事发生了变化:在更新之前,测试不会随机中断,而是在固定数量的测试中中断(在我们的例子中,639 次测试将导致测试中断,638、640、641...等将通过;648会再次破裂)。我认为这与茉莉花现在使用的随机种子有关。
这是完整的堆栈跟踪:
<!-- language: lang-none -->
Uncaught TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at subscribeTo (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/util/subscribeTo.js:41)
at subscribeToResult (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/util/subscribeToResult.js:11)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._innerSub (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:74)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:68)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber._next (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:51)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Subscriber.js:54)
at Observable._subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/util/subscribeToArray.js:5)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:43)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/Observable.js:29)
at MergeMapOperator.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapOperator.call (:9876/_karma_webpack_/webpack:/node_modules/rxjs/_esm5/internal/operators/mergeMap.js:29)
at ____________________Elapsed_3_ms__At__Thu_Dec_27_2018_10_03_35_GMT_0100__Mitteleurop_ische_Normalzeit_ ()
at Object.onScheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:108)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401)
at Object.onScheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:297)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:401)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:232)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:255)
at scheduleMacroTaskWithCurrentZone (:9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:1114)
at :9876/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:2090
噢,听起来事情变得不稳定了。最近我们遇到了单元测试随机中断的情况。您是否一直在更新 Angular 和 Karma 版本?
我们遇到的问题是,默认设置单元测试的方式(通过 Angular CLI)已经改变,并且旧的测试没有运行正确的测试async
ways.
您看到的错误确实与我们看到的不同,但我确信这是一个值得探索的途径,可以消除单元测试设置引入的任何脆弱性。
摘自https://angular.io/guide/testing#calling-compilecomponents https://angular.io/guide/testing#calling-compilecomponents
describe('BannerComponent', () => {
let component: BannerComponent
let fixture: ComponentFixture<BannerComponent>
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ],
}).compileComponents(); // compile template and css
}));
beforeEach(() => {
fixture = TestBed.createComponent(BannerComponent)
component = fixture.componentInstance
fixture.detectChanges()
})
it('should create', () => {
expect(component).toBeTruthy()
})
第一次要特别注意beforeEach()
其中有一个async() => {}
在那里,以及一个必需的.compileComponent()
.
第二beforeEach()
是定义和填充component
共享上下文中的变量describe()
.
我希望这可以帮助您找出导致片状现象的原因。由于源自 RxJS 的迭代器问题似乎指向依赖于先前测试设置的状态的测试,其中它接收 Observable 形式的输入。如果此 Observable 是在测试执行之后设置或定义的,那么您可能会遇到与您所描述的问题类似的问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)