6 правил, которым я следую, чтобы получить простые и стабильные тесты

Мне потребовалось несколько лет попыток и неудач, чтобы понять, что именно работает при написании тестов. Вот 6 правил, которым я всегда следую, независимо от того, какие тесты я пишу.

Следуйте шаблону AAA

Чистые модульные тесты следуют шаблону AAA:

  • Упорядочить: Настройте тестовый сценарий
  • Действовать: Выполнить бизнес-логику
  • Утверждать: Выразить некоторые ожидания

Это святой грааль простых тестов.

Одна концепция в одном тесте

Тестируйте одну концепцию в каждом модульном тесте. Если вы следуете шаблону AAA, это должно быть естественным.

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

Эмпирическое правило — если после вашего assert стоит act, вам следует подумать о том, чтобы разделить его на два отдельных теста.

Ваши тесты будет легче понять и легче исправить.

// Bad - mixing two concepts
it('should add new item into cart', () => {
  let cart = new Cart()
  cart.add(new Item('Shoes')) // <-- // Testing adding item into cart
  expect(cart.size).toBe(1);
  cart.removeAllItems(); // <-- Testing removing all items from cart
  expect(cart.size).toBe(0);
});

// Better - split it up
it('should add new item into cart', () => {
  let cart = new Cart();
  cart.add(new Item('Shoes');
  expect(cart.size).toBe(1);
});

it('should be possible to remove all items from cart', () => {
  let cart = new Cart([new Item()]);
  cart.removeAllItems();
  expect(cart.size).toBe(0);
});
Вход в полноэкранный режим Выход из полноэкранного режима

Избегайте логики в ваших тестах

Избегайте любых if, else, switch или троичных операторов в коде ваших тестов.

Как только вы используете любой из операторов потока управления — вы добавили логику в свой тест, и теперь вам нужен тест для вашего теста.

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

В таких случаях всегда лучше разделить тест на части и сделать его плоским и простым.

// Bad
it("should have focus when clicked", () => {
  render(<Input />)
  const input = screen.getByRole("input")

  // this null check is pointless
  if (input !== null) {
    click(input)
    expect(input).toHaveFocus()
  }
})

// Better
it("should have focus when clicked", () => {
  render(<Input />)
  click(screen.getByRole("input"))
  expect(screen.getByRole("input")).toHaveFocus()
})
Вход в полноэкранный режим Выход из полноэкранного режима

Оптимизируйте для простоты

Хороший тест — короткий, плоский, простой и приятный в работе. Когда вы смотрите на тест, вы должны сразу понять его замысел.

Не вставляйте тесты друг в друга. Это добавляет ненужную сложность. Каждый уровень вложенности добавляет в код дополнительную когнитивную сложность.

Рефакторите общий код настройки в фикстуру, чтобы избежать повторений.

Только публичный API

Если ваш тест делает что-то, чего не может сделать пользователь, скорее всего, он тестирует детали реализации.

Это запах кода. Любое изменение в базовой реализации приведет к поломке вашего теста.

Тестируйте только API, который может использовать ваш пользователь.

Используйте TDD для обеспечения покрытия

В 10/10 случаев, когда я использую TDD, покрытие кода поднимается выше 80%.

Начните со счастливого пути — убедитесь, что код работает для ваших основных сценариев использования.

Продолжайте с несчастливого пути — проверьте условия ошибки, неожиданный ввод или любые другие побочные случаи.

Вы можете пропустить тестирование тривиальных однострочных строк, геттеров и сеттеров.

Таким образом, вы легко достигнете отметки 80% покрытия.

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

Вот и все

Соблюдая эти несколько правил, вы сможете писать тесты, которые будут понятны всем, и работать с ними будет одно удовольствие.

Дайте мне знать, есть ли у вас другие правила, которым вы следуете, и почему.

Оцените статью
devanswers.ru
Добавить комментарий