Моки и стабы что это

от admin

За что я ценю тестирование и почему советую вам делать то же самое

Существует распространенное заблуждение, что написание тестов замедляет разработку. Преимущества от тестирования не всегда заметны сразу, работа пойдет быстрее в перспективе.

Внедряя тесты в приложения, я осознал насколько эффективно тестирование и как оно влияет на качество кода.

Краткий обзор стека технологий для тестирования

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

Enzyme — это тестовая утилита для React. Волшебство в том, что он отображает ваши компоненты React в Jest. Это позволяет эффективно протестировать JSX-код без ручной транскомпиляции. Вы создаете компоненты, используя один из трех методов: shallow, mount или render.

SuperTest позволяет совершать вызовы API без фактического вызова, перехватывая его. Вызов API может быть дорогостоящим и/или медленным для модульных тестов. Есть вероятность, что это серьезно замедлит тестирование.

Вот что я узнал.

Тестирование предотвращает регрессию

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

Звучит странно, но не все программисты могут объяснить код, который когда-то написали. Написание тестов улучшает понимание того, что именно ваша функция принимает в качестве аргумента и возвращает как результат.

Юнит-тестирование с помощью mocks и stubs

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

Чтобы этого избежать, вы можете заменить эти зависимости mocks или stubs. В итоге результат будет таким, как вы и ожидаете.

Например, вы хотите протестировать этот метод:

Главное различие между stubs и mocks заключается в том, что в одном случае мы управляем состоянием, а в другом — поведением.

Когда мы используем mocks, мы заменяем весь модуль на mock (ложный, тестовый объект, имитирующий настоящий). А stub — это функция, которая всегда выводит один и тот же результат, вне зависимости от того, что было подано на вход. Mocks используют для того, чтобы проверить, была ли функция вызвана с правильными аргументами, а stubs, чтобы протестировать, как функция работает с полученным ответом. Стабы нужны для проверки состояния метода, а моки используются для регулировки поведения.

Знайте что проверять не нужно

Имейте в виду, что не нужно тестировать весь код.

При помощи Jest, вы можете легко отслеживать свое тестовое покрытие, добавив —coverage в тестовый скрипт в CLI (интерфейс командной строки). Хотя это полезный метод, отнеситесь к нему с долей скептицизма. Способ, которым Jest измеряет охват теста, заключается в отслеживании стека вызовов, поэтому более высокое покрытие теста не означает, что ваши тесты эффективны.

Например, в предыдущем проекте я использовал библиотеку для реализации компонента карусели. Внутри компонента была функция для отображения списка на основе массива. Чтобы увеличить покрытие, я написал тест, чтобы подсчитать и сравнить количество отображаемых элементов с массивом. Компонент карусели изменил количество элементов, отображаемых на DOM, больше чем выход 1: 1, хотя реализация визуально отображала правильное количество элементов в браузере. Я решил отказаться от тестов, потому что они фактически тестировали библиотеку каруселей вместо моего кода.

Представим компонент Listings с методом renderCarousel, который отображает карусель из внешней библиотеки:

Name already in use

translations / node-hero / chapter9 / README.md

  • Go to file T
  • Go to line L
  • Copy path
  • Copy permalink
  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

Перевод книги Node Hero от RisingStack. Переведено с разрешения правообладателей.

В этой главе вы узнаете, что такое модульное тестирование (юнит-тестирование) в Node.js и как правильно тестировать ваши приложения.

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

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

Вы можете спросить: что я должен протестировать в своём приложении? Сколько тестов у меня должно быть?

Ответ варьируется, но, как правило, вы можете следовать рекомендациям, установленным пирамидой тестирования.

По сути, тестовая пирамида описывает, что вы должны писать модульные тесты, интеграционные тесты и e2e тесты. У вас должно быть больше интеграционных тестов, чем e2e и ещё больше модульных тестов.

Давайте посмотрим, как вы можете добавить модульные тесты для своих приложений!

Обратите внимание, что здесь мы не собираемся говорить об интеграционных и e2e тестах, поскольку они выходят далеко за рамки этого учебника.

Модульное тестирование Node.js-приложений

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

Вы должны писать тесты для публичных методов, а не для внутренней реализации данного модуля.

Анатомия модульного теста

Каждый модульный тест имеет следующую структуру:

  1. Настройка теста
  2. Вызов тестируемого метода
  3. Утверждение

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

Библиотеки, используемые для тестирования в Node.js

Для модульного тестирования мы собираемся использовать следующие библиотеки:

  • запуск тестов: mocha, альтернативно tape
  • библиотека утверждений: chai, альтернативно assert
  • шпионы, стабы и моки: sinon(для настройки тестов).

Шпионы, стабы и моки — что использовать и когда?

Прежде чем приступить к практике модульного тестирования, давайте разберёмся, что такое шпионы, стабы (заглушки) и моки!

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

Стабы похожи на шпионов, но они заменяют целевую функцию. Вы можете использовать стабы для управления поведением метода, чтобы форсировать какие-то события в коде (например, выброс ошибки) или предотвратить вызовы внешних ресурсов (таких как HTTP API).

Моки — это поддельные методы с заранее запрограммированным поведением и соглашениями.

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

Представьте, что вы хотите протестировать следующий модуль:

Этот модуль делает одну вещь: он сохраняет веб-страницу (основываясь на переданном URL) в файл на локальном компьютере. Чтобы протестировать этот модуль, мы должны «застабить» как модуль fs , так и модуль request .

Прежде чем начинать писать модульные тесты, в RisingStack мы обычно добавляем файл test-setup.spec.js для создания базовой настройки тестов, например создания песочниц Sinon. Это избавит вас от написания sinon.sandbox.create() и sinon.sandbox.restore() после каждого теста.

Кроме того, обратите внимание, что мы всегда ставим файлы тестов рядом с реализацией и даём им имя вида .spec.js . В нашем package.json вы можете найти следующие строки:

Как только у нас появились эти настройки, пришло время написать сами тесты!

Полные исходники примера вы можете найти здесь.

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

Этот отчёт будет включать следующие метрики:

  • покрытие строк кода,
  • покрытие инструкций,
  • покрытие ветвлений,
  • и покрытие функций.

В RisingStack мы используем istanbul для анализа покрытия кода. Вы должны добавить следующий скрипт к вашему package.json , чтобы использовать istanbul с mocha :

Как только вы это сделаете, вы получите что-то вроде:

Вы можете кликнуть мышью и на самом деле увидеть, что ваш исходный код аннотирован: какая часть протестирована, а какая — нет.

Тестирование может уберечь вас от множества неприятностей. Тем не менее, неизбежно наступает время отладки. В следующей главе Node Hero вы узнаете, как отлаживать Node.js-приложения.

Слушайте наш подкаст в iTunes и SoundCloud, читайте нас на Medium, контрибьютьте на GitHub, общайтесь в группе Telegram, следите в Twitter и канале Telegram, рекомендуйте в VK и Facebook.

По хардкору: дублеры, моки, стабы

Сегодня о тестах. Пост для тех, кто знаком с RSpec, но не понимает, что такое «мокать» и «застабить». Коротко, по делу и с примерами.

Дублер (test double)

Объект-каскадер, подменяющий реальный объект системы во время тестов:

Стаб (stub)

Заглушка для метода или объекта, возвращающая заданное значение:

Внимательный читатель со звездочкой уже заметил, что и в предыдущем примере с NotificationsController был стаб. Все верно: стаб — это дублер с зашитыми ответами.

Мок (mock)

Стаб с ожиданиями, которые RSpec проверит в конце теста:

Моки меняют порядок фаз в тесте. Вместо «Подготовка — Испытание — Проверка» получается «Проверка+Подготовка — Испытание». Если вам, как и мне, тяжело такое читать, используйте стаб с проверкой:

Дублеры, моки и стабы привязывают тесты к интерфейсу используемого объекта, а реальные объекты — к их реализации. Чтобы узнать об этой дилемме больше и понять, стоит ли вам мокать-стабить все подряд, почитайте:

P. S. Ещё больше постов о программировании, тестах и культуре разработки у меня в Телеграме. Подписывайтесь!

  • Стоп-комментарии
  • ← →
  • По хардкору: instance_double, verify_partial_doubles

Тестовый курс

Практический курс о тестировании в Ruby и Rails. С наставником, теорией, домашкой и дополнительными материалами: статьями, советами, видео.

Для разработчиков знакомых с Ruby и RSpec, но не до конца понимающих что и как тестировать. Для тех, кто прочитал RSpec Book, но не может написать тест с нуля. Для тех, кто исправляет баг за 5 минут, а потом 2 часа пишет тест.

Модульное тестирование

В этой главе вы узнаете, что такое модульное тестирование (юнит-тестирование) в Node.js и как правильно тестировать ваши приложения.

Тестирование Node.js-приложений

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

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

Вы можете спросить: что я должен протестировать в своём приложении? Сколько тестов у меня должно быть?

Ответ варьируется, но, как правило, вы можете следовать рекомендациям, установленным пирамидой тестирования.

По сути, тестовая пирамида описывает, что вы должны писать модульные тесты, интеграционные тесты и e2e тесты. У вас должно быть больше интеграционных тестов, чем e2e и ещё больше модульных тестов.

Давайте посмотрим, как вы можете добавить модульные тесты для своих приложений!

Обратите внимание, что здесь мы не собираемся говорить об интеграционных и e2e тестах, поскольку они выходят далеко за рамки этого учебника.

Модульное тестирование Node.js-приложений

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

Вы должны писать тесты для публичных методов, а не для внутренней реализации данного модуля.

Анатомия модульного теста

Каждый модульный тест имеет следующую структуру:

  1. Настройка теста
  2. Вызов тестируемого метода
  3. Утверждение

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

Библиотеки, используемые для тестирования в Node.js

Для модульного тестирования мы собираемся использовать следующие библиотеки:

  • запуск тестов: mocha, альтернативно tape
  • библиотека утверждений: chai, альтернативно assert
  • шпионы, стабы и моки: sinon(для настройки тестов).

Шпионы, стабы и моки — что использовать и когда?

Прежде чем приступить к практике модульного тестирования, давайте разберёмся, что такое шпионы, стабы (заглушки) и моки!

Шпионы

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

Стабы

Стабы похожи на шпионов, но они заменяют целевую функцию. Вы можете использовать стабы для управления поведением метода, чтобы форсировать какие-то события в коде (например, выброс ошибки) или предотвратить вызовы внешних ресурсов (таких как HTTP API).

Моки — это поддельные методы с заранее запрограммированным поведением и соглашениями.

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

Представьте, что вы хотите протестировать следующий модуль:

Этот модуль делает одну вещь: он сохраняет веб-страницу (основываясь на переданном URL) в файл на локальном компьютере. Чтобы протестировать этот модуль, мы должны «застабить» как модуль fs , так и модуль request .

Прежде чем начинать писать модульные тесты, в RisingStack мы обычно добавляем файл test-setup.spec.js для создания базовой настройки тестов, например создания песочниц Sinon. Это избавит вас от написания sinon.sandbox.create() и sinon.sandbox.restore() после каждого теста.

Кроме того, обратите внимание, что мы всегда ставим файлы тестов рядом с реализацией и даём им имя вида .spec.js . В нашем package.json вы можете найти следующие строки:

Как только у нас появились эти настройки, пришло время написать сами тесты!

Полные исходники примера вы можете найти здесь.

Покрытие кода

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

Этот отчёт будет включать следующие метрики:

  • покрытие строк кода,
  • покрытие инструкций,
  • покрытие ветвлений,
  • и покрытие функций.

В RisingStack мы используем istanbul для анализа покрытия кода. Вы должны добавить следующий скрипт к вашему package.json , чтобы использовать istanbul с mocha :

Как только вы это сделаете, вы получите что-то вроде:

Вы можете кликнуть мышью и на самом деле увидеть, что ваш исходный код аннотирован: какая часть протестирована, а какая — нет.

Читать:
Сколько всего суббот и воскресений в году

Related Posts