ОБНОВЛЕНИЕ: теперь я стараюсь вообще избегать использования перехватчиков жизненного цикла тестирования или вложенных описаний. Послушайте, я расскажу об этом 3 минуты здесь. Фактически, теперь, когда я использую Jest (изучать Jest), я даже не использую описать. Я считаю, что так намного лучше. Но если вы все равно хотите использовать хуки жизненного цикла, этот пост по-прежнему актуален.

С моккожасмином) у вас есть несколько зацепок в жизненном цикле тестирования: описать, до, после, beforeEach, afterEach и it. Что все это означает? Когда я могу использовать одно вместо другого? Что мне добавить в каждую из них? Я постараюсь ответить на этот вопрос, насколько мне удастся, исходя из моего личного опыта.

описывать

Используется для группировки тестов по модулю или компоненту. Вы можете вкладывать операторы описания, чтобы более точно описывать часть единицы. Я вкладываю их, когда тестирую модуль, у которого есть несколько методов, которые я могу вызвать. Например:

import wand from './wand'
describe(`wand`, function() {
  describe(`createUnicorn`, function() {
   // test wand.createUnicorn
  })
})

В контексте E2E-тестирования страницы я бы сгруппировал похожие тесты, которые требуют аналогичной настройки / удаления и / или определенных частей или компонентов тестируемой страницы. Честно говоря, у меня ограниченный опыт проведения этого типа тестирования, но общим правилом должно быть группирование вещей, которые можно описать вместе.

до после

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

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

Что касается размещения, я бы порекомендовал вам разместить их там, где вы когнитивно думаете, что они должны работать:

import wand from './wand'
describe(`wand`, function() {
  describe(`createUnicorn`, function() {
    before(`optional descriptive message`, function() {
      // set up state before any of the tests run
    })
    // test wand.createUnicorn
    after(`optional descriptive message`, function() {
      // tear down state after all of the tests run
    })
  })
})

beforeEach / afterEach

Они выполняются для каждого отдельного теста. Итак, если у вас есть 3 теста, каждый из них будет выполняться по 3 раза. Используйте это только для того, что есть во всех ваших утверждениях. Я часто использую это, чтобы настроить какое-то состояние, которое должно существовать (когда то, что я тестирую, не является апатридом 😒) или для создания удобных объектов / функций, которые не имеют состояния.

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

import wand from './wand'
describe(`wand`, function() {
  describe(`createUnicorn`, function() {
    before(`optional descriptive message`, function() {
      // set up state before any of the tests run
    })
    beforeEach(`optional descriptive message`, function() {
      // set up state before each of the tests run
    })
    // test wand.createUnicorn
    afterEach(`optional descriptive message`, function() {
      // tear down state after each of the tests run
    })
    after(`optional descriptive message`, function() {
      // tear down state after all of the tests run
    })
  })
})

it

Вот тут-то и появляются ваши фактические утверждения. Если в них нет утверждений, вы делаете это неправильно. Каждый оператор it должен быть полностью изолирован от любых других операторов it. Каждый из них должен работать без каких-либо других тестов.

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

Лучший тест проверяет ожидаемый результат с фактическим результатом

Это действительно легко сделать, когда вы тестируете что-то без состояния, но на самом деле многим из нас (особенно в сообществе Angular) очень трудно писать компоненты (особенно директивы) без состояния. Надеюсь, написание тестов перед внедрением поможет побудить вас писать файлы без сохранения состояния, потому что их проще тестировать.

В любом случае, как и следовало ожидать, ваш оператор it будет находиться между beforeEach и afterEach:

import wand from './wand'
describe(`wand`, function() {
  describe(`createUnicorn`, function() {
    before(`optional descriptive message`, function() {
      // set up state before any of the tests run
    })
    beforeEach(`optional descriptive message`, function() {
      // set up state before each of the tests run
    })
    it(`should create me a new unicorn object`, function() {
      const actual = wand.createUnicorn()
      const expected = {name: 'Fred'}
      expect(actual).to.deep.equal(expected)
    })
    afterEach(`optional descriptive message`, function() {
      // tear down state after each of the tests run
    })
    after(`optional descriptive message`, function() {
      // tear down state after all of the tests run
    })
  })
})

Вывод

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

Я рекомендую вам ознакомиться с публикацией Эрика Эллиота 5 вопросов, на которые должен ответить каждый модульный тест. Вот вопросы:

  1. Что ты тестируешь?
  2. Что ему делать?
  3. Каков фактический результат?
  4. Каков ожидаемый результат?
  5. Как можно воспроизвести тест?

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

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

QYMA

(Вопросы, которые вы могли бы задать)

В: Почему вы используете шаблонные литералы для своих строк !? A: Это