beforeEach 在 angular 4 升级的 karma + Mocha 中失败

beforeEach fails in karma + Mocha with angular 4 upgrade

上下文

我已经确认 "green" 建立在 master branch 之上,它使用 angular-cli 1.0.0 和旧的 angular2 依赖项。我的 Objective 是从 angular2 升级到 angular4.

Post 升级问题

工作配置

具体package.json如下。

...
"dependencies": {
    "@angular/common": "^2.4.0",
    "@angular/compiler": "^2.4.0",
    "@angular/core": "^2.4.0",
    "@angular/forms": "^2.4.0",
    "@angular/http": "^2.4.0",
    "@angular/platform-browser": "^2.4.0",
    "@angular/platform-browser-dynamic": "^2.4.0",
    "@angular/router": "^3.4.0",
    ...
},
"devDependencies": {
    "@angular/cli": "1.0.0",
    "@angular/compiler-cli": "^2.4.0",
    ...
}

测试结果如下 Chromium 53.0.2785 (Ubuntu 0.0.0): Executed 82 of 83 (skipped 1) SUCCESS (5.674 secs / 0.061 secs)

Angular 4 次升级未通过测试

当我尝试用非常 specific diff the application runs successfully, however I get failed/repeated tests for the upgrade like so Chromium 53.0.2785 (Ubuntu 0.0.0): Executed 127 of 83 (32 FAILED) (skipped 2) (7.521 secs / 0.101 secs)

升级 angular4 依赖项时

令我着迷的是,除了我实际拥有的测试数量外,还有 44 项测试 运行。似乎唯一失败的测试是 duplicate 测试 运行ning 并且它们在成功后直接失败。经调查,如果这些测试之前不是 运行

,这些测试似乎会失败
Chrome 56.0.2924 (Linux 0.0.0): Executed 67 of 83 (13 FAILED) (0 secs / 0.11 secs)
      ✔ will raise a houseCreated event
Chrome 56.0.2924 (Linux 0.0.0) HouseListComponent when valid input is provided (while in create mode) will raise a houseCreated event FAILED
    AssertionError: expected { Object (country, state, ...) } to equal { Object (country, state, ...) }
        at Context.<anonymous> (webpack:///src/app/housing/components/edit/house-edit.component.spec.ts:69:40 <- src/test.ts:26683:54)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:365:0 <- src/polyfills.ts:1520:26)
        at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:88673:39)
        at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:364:0 <- src/polyfills.ts:1519:32)
        at Zone.run (webpack:///~/zone.js/dist/zone.js:125:0 <- src/polyfills.ts:1280:43)
        at Context.<anonymous> (webpack:///~/zone.js/dist/mocha-patch.js:88:0 <- src/test.ts:88521:33)
        at webpack:///~/zone.js/dist/mocha-patch.js:140:0 <- src/test.ts:88573:33
        at ZoneDelegate.invokeTask (webpack:///~/zone.js/dist/zone.js:398:0 <- src/polyfills.ts:1553:31)
        at Zone.runTask (webpack:///~/zone.js/dist/zone.js:165:0 <- src/polyfills.ts:1320:47)
        at drainMicroTaskQueue (webpack:///~/zone.js/dist/zone.js:593:0 <- src/polyfills.ts:1748:35)
        at ZoneTask.invoke (webpack:///~/zone.js/dist/zone.js:464:0 <- src/polyfills.ts:1619:25)
        at timer (webpack:///~/zone.js/dist/zone.js:1540:0 <- src/polyfills.ts:2695:29)
Chrome 56.0.2924 (Linux 0.0.0): Executed 68 of 83 (14 FAILED) (0 secs / 0.111 secs)
      ✖ will raise a houseCreated event 

损坏的配置

...
"dependencies": {
    "@angular/common": "^4.0.1",
    "@angular/compiler": "^4.0.1",
    "@angular/core": "^4.0.1",
    "@angular/forms": "^4.0.1",
    "@angular/http": "^4.0.1",
    "@angular/platform-browser": "^4.0.1",
    "@angular/platform-browser-dynamic": "^4.0.1",
    "@angular/router": "^4.0.1",
    ...
},
"devDependencies": {
    "@angular/cli": "1.0.0",
    "@angular/compiler-cli": "^4.0.1",
    ...
}

在不同的 运行ner

上进行相同的测试

为了确定问题是测试还是 运行ner,我 运行 用 wallabyjs 运行ner 进行了完全相同的测试,我得到 No failing tests, 82 passing 使用升级后的 angular4 依赖项与 master 完美内联。这似乎表明问题是特定于业力而不是测试。

资源

错误

有许多测试错误,但它们似乎都与 beforeEach 有关。测试模块不应该已经实例化,这似乎是重复测试的奇怪副作用。

Chrome 56.0.2924 (Linux 0.0.0) car reducer "before each" hook for "will return array removes existing values when state is not empty" FAILED
    Error: Cannot configure the test module when the test module has already been instantiated. Make sure you are not using `inject` before `TestBed.configureTestingModule`.
        at TestBed.Array.concat.TestBed._assertNotInstantiated (webpack:///~/@angular/core/@angular/core/testing.es5.js:749:0 <- src/test.ts:25844:19) [ProxyZone]
        at TestBed.Array.concat.TestBed.configureTestingModule (webpack:///~/@angular/core/@angular/core/testing.es5.js:671:0 <- src/test.ts:25766:14) [ProxyZone]
        at Function.Array.concat.TestBed.configureTestingModule (webpack:///~/@angular/core/@angular/core/testing.es5.js:576:0 <- src/test.ts:25671:22) [ProxyZone]
        at Context.<anonymous> (webpack:///src/app/car/reducers/car.reducer.spec.ts:30:12 <- src/test.ts:31440:27) [ProxyZone]
        at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:88673:39) [ProxyZone]
        at Zone.run (webpack:///~/zone.js/dist/zone.js:125:0 <- src/polyfills.ts:1280:43) [<root> => ProxyZone]
        at Context.<anonymous> (webpack:///~/zone.js/dist/mocha-patch.js:88:0 <- src/test.ts:88521:33) [<root>]

然后在每个失败之前我们得到更多关于 属性 call

的错误
Chrome 56.0.2924 (Linux 0.0.0) car reducer "before each" hook for "will return array removes existing values when state is not empty" FAILED
    TypeError: Cannot read property 'call' of undefined
        at ZoneDelegate.invokeTask (webpack:///~/zone.js/dist/zone.js:398:0 <- src/polyfills.ts:1553:31)
        at Zone.runTask (webpack:///~/zone.js/dist/zone.js:165:0 <- src/polyfills.ts:1320:47)
        at ZoneTask.invoke (webpack:///~/zone.js/dist/zone.js:460:0 <- src/polyfills.ts:1615:38)
        at timer (webpack:///~/zone.js/dist/zone.js:1540:0 <- src/polyfills.ts:2695:29)
Chrome 56.0.2924 (Linux 0.0.0): Executed 45 of 83 (8 FAILED) (0 secs / 0.092 secs)

frameworks 数组中的多个引用应避免使用 Karma。使用 plugins 代替

围绕失败 beforeEach 的这个问题实际上是转移注意力,是重复测试的副作用。似乎正在执行的生命周期是:

  1. beforeEach
  2. it('myTest1') 通过
  3. it('myTest1') 失败
  4. beforeEach
  5. it('myTest2') 通过
  6. it('myTest2') 失败

如果我们停止重复测试,那么 beforeEach 问题实际上并不存在。这在 karma issue 中被消化和演示,结果是用户(我的)错误。

为了停止重复测试,我们需要更新 karma.conf.js 中的 frameworks 数组并减少框架引用的数量,并使用已经被引用的 plugins 代替。

frameworks: ['mocha', 'chai', 'sinon-chai', '@angular/cli'],

变成

frameworks: ['mocha', '@angular/cli'],

分辨率

停止重复测试,beforeEach 将按预期运行。工作提交可以是 found here.