Vk com minitest: minitest/minitest: minitest provides a complete suite of testing facilities supporting TDD, BDD, mocking, and benchmarking.

BDD на Rails с Minitest, часть 1: запуск и запуск

24 ноября 2021 г. · Новости Semaphore

Марко Анастасов — инженер-программист, автор и соучредитель Semaphore. Он работал над созданием и масштабированием Semaphore от идеи до облачной платформы, используемой некоторыми инженерными группами по всему миру.

8 минут чтения

Поделиться

Содержимое

Это гостевой пост в блоге от Криса Коттома, давнего разработчика Ruby и Rails, фрилансера, гордого отца и создателя лучшего перца чили кон карне, который можно найти в Праге. В настоящее время он день и ночь работает над готовящейся электронной книгой The Minitest Cookbook.


Разработка, основанная на поведении (BDD), завоевала популярность в сообществах Ruby и Rails, в немалой степени благодаря полнофункциональному набору инструментов, который позволяет осуществлять разработку, руководствуясь тестами на многих различных уровнях приложения.

Первыми лидерами в этой области были RSpec и Cucumber, каждый из которых привлек миллионы пользователей и десятки, если не сотни участников. Но все большее число Rubyists начали создавать и использовать стеки тестирования на основе Minitest, который предоставляет сопоставимый набор функций модульного тестирования в упрощенном, упрощенном пакете.

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

Настройка

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

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

* minitest для модульного тестирования
* capybara для приемочного тестирования
* minitest-rails-capybara для интеграции обеих библиотек тестирования с Rails
* minitest-reporters для настройки вывода тестов, включая раскрашивание

Чтобы установить необходимые драгоценные камни, нам нужно добавить следующие строки в Gemfile.

 группа: тест сделать
  гем 'minitest-rails-capybara'
  gem 'минитест-репортеры'
конец
 

Minitest поддерживает два разных метода написания тестов: синтаксис в стиле утверждений по умолчанию, напоминающий класс Test::Unit, и синтаксис в стиле спецификаций, который больше напоминает RSpec. Лично я предпочитаю синтаксис в стиле спецификаций, поэтому в этом примере мы будем писать все тесты как спецификации.

Чтобы заставить генераторы создавать тестовые примеры в стиле спецификаций, нам нужно сообщить им об этом, добавив следующий блок в config/application.rb:0003
 # Используйте Minitest для генерации новых тестов.
config.generators делают |g|
  g.test_framework: минитест, спецификация: истина
конец
 

Далее мы обновим наш test_helper.rb, запустив генератор minitest-rails: rails generate minitest:install. Новая версия помощника по тестированию требует minitest-rails в качестве основы для всех тестов. Мы изменим это немного дальше, чтобы окончательная версия также требовала rails-minitest-capybara и minitest-reporters и настраивала репортеры. Готовый продукт должен выглядеть примерно так:

 ENV["RAILS_ENV"] = "тест"
требуется File.expand_path("../../config/environment", __FILE__)
требуют "rails/test_help"
требуют "minitest/rails"
требуется "minitest/rails/capybara"
требуют "минитест/репортеры"
Minitest::Reporters.use!(
  Minitest::Reporters::SpecReporter.new,
  ЭНВ,
  Минитест.
backtrace_filter ) класс ActiveSupport::TestCase ActiveRecord::Migration.check_pending! приспособления: все конец

Неудачная функция

Самой основной функцией нашего списка дел будет страница, отображающая список, содержащий наши задачи, поэтому мы начнем с создания новой функции Capybara с помощью предоставленного генератора: rails generate минитест:функция ToDoList. Это инициализирует шаблонный тест в test/features, который мы затем можем обновить в соответствии с нашими потребностями. Мы начнем с написания самого простого возможного теста для этого приложения с помощью minitest-rails-capybara, обеспечивающего хороший мост между двумя мирами — упаковывая Capybara DSL в виде утверждений и ожиданий в стиле Minitest.

 требуется "test_helper"
функция "Список дел" делать
  сценарий "отображает список дел" do
    посетить root_path
    page.must_have_css("#items")
  конец
конец
 

Когда я запускаю свой тестовый набор, он взрывается. Предсказуемо.

 Проверка функций списка дел
  test_0001_отображает список дел ОШИБКА (0,00 с)
NameError: NameError: неопределенная локальная переменная или метод `root_path' для #<#:0x007f83c4153930>
        test/features/to_do_list_test. rb:5:in `блок (2 уровня) в '
        test/features/to_do_list_test.rb:5:in `блок (2 уровня) в '
Завершено за 0,00508 с.
1 тест, 0 утверждений, 0 сбоев, 1 ошибка, 0 пропусков
 

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

The Red-Green Dance

Первоначальная ошибка возникает из-за того, что в приложении еще не определены маршруты, поэтому нам нужно добавить корневой путь, указывающий на гипотетический ItemsController, в config/routes.rb:

 Rails.application.routes.draw делать
  root для: 'items#index'
конец
 

При повторном запуске тестов ошибка изменилась.

 эрб
Тест функций списка дел
  test_0001_отображает список дел ОШИБКА (0,00 с)
ActionController::RoutingError: ActionController::RoutingError: неинициализированная константа ItemsController
        test/features/to_do_list_test. rb:5:in `блок (2 уровня) в '
        test/features/to_do_list_test.rb:5:in `блок (2 уровня) в '
Завершено за 0,00736 с.
1 тест, 0 утверждений, 0 сбоев, 1 ошибка, 0 пропусков
 

Маршрут, который мы только что определили, ожидает ItemsController с действием index. Было бы достаточно легко просто создать или сгенерировать это, но наш рабочий процесс диктует, что сначала нам нужен неудачный тест, описывающий, как должно выглядеть это действие контроллера. На данный момент нас интересует кратчайший путь для отображения представления с пустым списком элементов. Это производит такой тест контроллера:

 требуют "test_helper"
описать "ItemsController" сделать
  описать "GET :index" сделать
    прежде чем сделать
      получить: индекс
    конец
    он "отображает элементы/индекс"
      must_render_template "элементы/индекс"
    конец
    это "отвечает успехом" делать
      must_respond_with: успех
    конец
  конец
конец
 

Большая часть тяжелой работы для простых проверок, которые вы видите здесь, обеспечивается ActionController::TestCase Rails с ожиданиями в стиле спецификации, предоставляемыми гемом minitest-rails в виде синтаксического сахара.

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

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

 Проверка функций списка дел
  test_0001_отображает список дел ОШИБКА (0,00 с)
ActionController::RoutingError: ActionController::RoutingError: неинициализированная константа ItemsController
        test/features/to_do_list_test.rb:5:in `блок (2 уровня) в '
        test/features/to_do_list_test.rb:5:in `блок (2 уровня) в '
ItemsController::GET :индекс
  test_0001_renders элементы/индекс ОШИБКА (0,00 с)
NameError: NameError: невозможно разрешить контроллер для ItemsController::GET: index
  test_0002_отвечает с успехом ОШИБКА (0,00 с)
NameError: NameError: невозможно разрешить контроллер для ItemsController::GET: index
Finished in 0.01033s
3 теста, 0 утверждений, 0 сбоев, 3 ошибки, 0 пропусков
 

Круто, ошибок практически не бывает! Поскольку все это вызвано отсутствием ItemsController, мы можем исправить их, создав его. Мы будем использовать генератор Rails, убедившись, что тест контроллера, с которым мы уже начали работать, не перезаписывается при появлении соответствующего запроса. Как только это будет сделано, повторный запуск теста даст следующий результат.

 Проверка функций списка дел
  test_0001_отображает список задач FAIL (0,02 с)
Minitest::Assertion: ожидается найти #items.
        test/features/to_do_list_test.rb:6:in `блок (2 уровня) в '
ItemsController::GET :индекс
  test_0001_renders элементы/индекс ПРОШЕЛ (0,00 с)
  test_0002_отвечает успешно ПРОШЕЛ (0,00 с)
Finished in 0.03471s
3 теста, 3 утверждения, 1 сбой, 0 ошибок, 0 пропусков
 

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

 erb
<%%= content_tag :div, class: 'items' do %>
<%% End -%>
 

И когда мы снова запустим тесты:

 To Do List Feature Test
  test_0001_отображает список задач ПРОШЕЛ (0,02 с)
ItemsController::GET :индекс
  test_0001_renders элементы/индекс ПРОШЕЛ (0,00 с)
  test_0002_отвечает успешно ПРОШЕЛ (0,00 с)
Закончил в 0,03379с
3 теста, 3 утверждения, 0 сбоев, 0 ошибок, 0 пропусков
 

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Закрыть
Menu