Угловые 6 единиц тестов: ошибка была выбрана afterAll\nReferenceError: не удается найти переменную: $ throw

При запуске моих модульных тестов время от времени, даже если они пройдут, в конце всех запущенных тестов я получу следующую ошибку.

На моем проекте Jenkins CI работает PhantomJS:

.PhantomJS 2.1.1 (Linux 0.0.0) ERROR
  {
    "message": "An error was thrown in afterAll\nReferenceError: Can't find variable: $ thrown",
    "str": "An error was thrown in afterAll\nReferenceError: Can't find variable: $ thrown"
  }

Или в Chrome:

Chrome 67.0.3396 (Windows 7 0.0.0) ERROR
  {
    "message": "An error was thrown in afterAll\n[object ErrorEvent] thrown",
    "str": "An error was thrown in afterAll\n[object ErrorEvent] thrown"
  }

У меня также есть действительно ненадежные тесты, не меняя ничего в несколько раз, когда они преуспеют, а в других случаях те же тесты терпят неудачу, поэтому я знал, что происходит что-то странное.

Ответы

Ответ 1

Мы столкнулись с аналогичными проблемами, как с такой же периодической ошибкой, и с периодическими неудачными испытаниями. По-видимому, это связано с тем, что при обновлении до Angular 6 мы также обновили до Jasmine 3, где выполнение тестов в случайном порядке, по-видимому, теперь по умолчанию. Установив случайное значение false, мы больше не видим этих проблем. Мы сделали это, добавив эту настройку в файл karma.conf.js:

  config.set({
    client: {
      jasmine: {
        random: false
      }
    }
  })

Ответ 2

Моя проблема заключалась в том, что у меня было условие гонки в моих тестах из-за очень глупых способов настройки моих тестов, но я хотел документировать это здесь, потому что я изо всех сил пытался найти ответ на мою проблему в Интернете.

То, что я как-то сделал, было объявить две beforeEach функциями для настройки моего теста, и один из двух был асинхронным, поэтому у меня было условие гонки, где иногда они выходили из строя и не выполнялись.

Вот как выглядел мой тест:

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ HomeComponent ]
    })
    .compileComponents();
  }));

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

Поэтому, чтобы решить эту проблему, я поставил все настройки в одну, синхронную beforeEach.

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [HomeComponent]
    }).compileComponents();
    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

Я потратил слишком много времени, пытаясь понять это, поэтому я помещаю его сюда, чтобы спасти кого-то еще.

Ответ 3

У меня была аналогичная проблема, мне кажется, что с угловыми v6 & Кармы v3 этой туманной afterAll ошибка начала появляться (https://github.com/jasmine/jasmine/issues/1523). Для меня эта ошибка не провалила тест, но провалила набор.

После рассмотрения многих ответов на эту проблему, кажется, что причина почти всегда различна, что затрудняет поиск помощи в Интернете. Можно надеяться, что в какой-то момент будет добавлено обновление для исправления ошибки.

Моя ошибка

[INFO] HeadlessChrome 71.0.3542 (Linux 0.0.0) DialogComponent #apply should save. FAILED
[INFO]  Uncaught TypeError: Cannot read property 'nativeElement' of undefined thrown
[INFO]       [31m✗ [39m[31mshould save.[39m
[INFO]  Uncaught TypeError: Cannot read property 'nativeElement' of undefined thrown
[INFO] 
[INFO] HeadlessChrome 71.0.3542 (Linux 0.0.0) DialogComponent #apply should save. FAILED
[INFO]  Uncaught TypeError: Cannot read property 'nativeElement' of undefined thrown
[INFO] HeadlessChrome 71.0.3542 (Linux 0.0.0) DialogComponent #apply should save. FAILED
[INFO]  Uncaught TypeError: Cannot read property 'nativeElement' of undefined thrown
[INFO] HeadlessChrome 71.0.3542 (Linux 0.0.0) ERROR
[INFO]   {
[INFO]     "message": "An error was thrown in afterAll\nUncaught TypeError: Cannot read property 'nativeElement' of undefined thrown\nUncaught TypeError: Cannot read property 'nativeElement' of undefined thrown",
[INFO]     "str": "An error was thrown in afterAll\nUncaught TypeError: Cannot read property 'nativeElement' of undefined thrown\nUncaught TypeError: Cannot read property 'nativeElement' of undefined thrown"
[INFO]   }

Нахождение проблемного теста

Я получил это сообщение об ошибке afterAll и понятия не имел, что его вызвало, или какой тест вызвал его. Первым делом я установил karma-spec-reporter: npm install karma-spec-reporter --save-dev

Добавьте это в массив плагинов в файле karma.conf.js: это даст вам репортер спецификаций, добавьте spec в массив reporters: ['spec'],

При следующем запуске теста вы увидите ошибку afterAll в консоли после проблемного теста.

Моя проблема/решение

Я обнаружил, что тест вызывает htmlElement.click(). Я изменил это на: htmlElement.dispatchEvent(new Event('click)) И вуаля тесты начали проходить.

Резюме

Как правило, я избегаю использования .click() в HTMLElement. Кроме того, когда пользователи взаимодействуют с пользовательским интерфейсом, это происходит с помощью событий, поэтому он более корректно имитирует действия пользователей, что всегда хорошо при тестировании.

Ответ 4

Моя конкретная проблема с этой ошибкой была вызвана отсутствием подделки подкомпонентов компонента, который я тестировал. В этом случае у меня был компонент домашней страницы с двумя подкомпонентами, которые требовали деклараций для подкомпонентов, которые я не сменил.

В результате у подкомпонентов были реальные зависимости, которые периодически приводили к сбою тестов таким неочевидным образом (похоже, что разные тесты случайно дают сбой, но это не так).

В этом случае довольно хорошо работает насмешка:

@Component({
    selector: 'app-exercise',
    template: '<p>Mock Exercise Component</p>'
})
class MockExerciseComponent {
}

@Component({
    selector: 'app-user',
    template: '<p>Mock User Component</p>'
})
class MockUserComponent {
}

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

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            // note you need to mock sub components!
            declarations: [HomepageComponent, MockExerciseComponent, MockUserComponent],

Ответ 5

Когда эта ошибка происходит, проверьте браузер, открытый karma, и проверьте его консоль на наличие ошибок. Обычно там будет трассировка стека, которая поможет вам решить проблему. Это также относится к другим ошибкам, вызванным кармой, которые не являются информативными.