Статьи

Узнайте первые лучшие практики для Rails и RSpec

Эта статья была рецензирована Томом Паркином . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Написание кода без тестирования может быть обманчиво гладким; тот, который, к сожалению, останавливается, когда вы начинаете работать с другими разработчиками. Это руководство предназначено для того, чтобы помочь разработчикам Ruby on Rails (особенно новичкам) в настройке набора тестов RSpec с использованием передовых методик , основанных на поведенческой разработке. Я знаю, что тестирование может быть болезненным, когда вы только начинаете. Есть много ресурсов онлайн, чтобы помочь вам в этом путешествии. Я надеюсь, что это будет полезно для новых разработчиков Ruby on Rails, так как я только начал тестировать себя.

В этом уроке мы узнаем следующее:
* Как настроить — RSpec, Capybara, Shoulda-Matchers, Очиститель базы данных
* Как создать фабрику, используя Factory Girl Rails и Faker
* Как написать спецификацию модели
* Как написать спецификации контроллера
* Как написать характеристики
* Как проверить спецификацию с помощью SimpleCov

Rails Application

rails new myapp 

Установка RSpec

Откройте ваш Gemfile и добавьте rspec-rails в группу development и test :

 group :development, :test do gem 'byebug' gem 'rspec-rails', '~> 3.4' end 

Установите драгоценные камни:

 bundle install 

Теперь запустите:

 rails generate rspec:install 

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

Должны-Matchers и Очиститель базы данных

Откройте ваш Gemfile и добавьте test группу, содержащую гемы musta-matcher и database_cleaner :

Gemfile

 group :test do gem 'shoulda-matchers', '~> 3.0', require: false gem 'database_cleaner', '~> 1.5' end 

Запустите bundle install .

Конфигурация Должно-Matchers

В случае использования Ifa-Matchers однострочные средства сопоставления с RSpec используются при тестировании функциональности Rails, что мы кратко рассмотрим. Откройте файл spec / rails_helper.rb и настройте shoulda-matchers для работы с RSpec, вставив следующее:

 require 'shoulda/matchers' Shoulda::Matchers.configure do |config| config.integrate do |with| with.test_framework :rspec with.library :rails end end 

Конфигурация очистителя базы данных

Database Cleaner — это набор стратегий для очистки базы данных в Ruby между тестовыми прогонами. Это помогает обеспечить чистое состояние для тестирования.

Чтобы интегрировать database_cleaner , выполните следующую настройку для spec / rails_helper.rb :

 config.use_transactional_fixtures = false 

Создайте новый каталог с именем support внутри вашей директории spec:

 mkdir spec/support 

Внутри него создайте новый файл database_cleaner.rb и вставьте следующее:

 RSpec.configure do |config| config.before(:suite) do DatabaseCleaner.clean_with(:truncation) end config.before(:each) do DatabaseCleaner.strategy = :transaction end config.before(:each, :js => true) do DatabaseCleaner.strategy = :truncation end config.before(:each) do DatabaseCleaner.start end config.after(:each) do DatabaseCleaner.clean end end 

При этом устанавливается database_cleaner который будет очищать базу данных между каждым модульным тестом и набором тестов.

Настройка капибары

Capybara — это среда автоматизации, используемая для создания функциональных тестов, которые имитируют взаимодействие пользователей с вашим приложением. Добавьте гем capybara в группу :development, :test ,: :development, :test в вашем Gemfile , ту же группу, в которую вы добавили rspec-rails :

 gem 'capybara', '~> 2.5' 

и bundle install .

Откройте ваш spec_helper.rb и потребуйте гем капибары:

 ***spec/spec_helper.rb*** ... require 'capybara/rspec' 

Faker и Factory Girl Setup

Faker полезен для генерации случайных данных для вашего теста. Вы увидите, как использовать его с factory_girl_rails при создании фабрики. Добавьте гем faker в группу :test в вашем Gemfile :

 gem 'faker', '~> 1.6.1' 

Factory Girl позволяет создавать нужные вам объекты в ваших тестах, которые могут включать значения по умолчанию. С помощью faker вы сможете создавать случайные объекты для вашего теста, а не использовать только одно значение по умолчанию.

Добавьте гем factory_girl_rails в :development, :test factory_girl_rails :development, :test group:

 gem 'factory_girl_rails', '~> 4.5.0' 

Затем bundle install .

На этом этапе ваш Gemfile должен выглядеть так:

 source 'https://rubygems.org' gem 'rails', '4.2.4' gem 'sqlite3' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.1.0' gem 'jquery-rails' gem 'turbolinks' gem 'jbuilder', '~> 2.0' gem 'sdoc', '~> 0.4.0', group: :doc group :development, :test do gem 'byebug' gem 'rspec-rails', '~> 3.4' gem 'factory_girl_rails', '~> 4.5' gem 'capybara', '~> 2.5' end group :development do gem 'web-console', '~> 2.0' gem 'spring' end group :test do gem 'shoulda-matchers', '~> 3.0', require: false gem 'database_cleaner', '~> 1.5' gem 'faker', '~> 1.6.1' end 

Создание фабрики

Создайте каталог с именем factory в вашей папке spec , а также добавьте файл с именем вашей модели. Например, contact.rb

 ***spec/factories/contacts.rb*** FactoryGirl.define do factory :contact do full_name { Faker::Name.name } email { Faker::Internet.email } phone_number { Faker::PhoneNumber.phone_number } address { Faker::Address.street_address } end end 

Выше я только что показал вам, как создавать приборы, используя factory_girl_rails и faker . Вам не нужно явно вводить объекты. Factory Girl использует случайные (поддельные) значения, сгенерированные faker для создания фабрик, которые будут использоваться при каждом запуске теста.

Модель Характеристики

Мы хотим убедиться, что фабрика, которую мы создали выше, действительна для модели. Создайте файл в папке model / spec для вашей модели:

 ***spec/models/contact_spec.rb*** require 'rails_helper' RSpec.describe Contact, type: :model do it "has a valid factory" do expect(contact).to be_valid end end 

С вашего терминала запустите:

 rspec spec/models/contact_spec.rb 

Это покажет ошибку, потому что у вас нет модели Contact . Перейдите в терминал, создайте модель и перенесите базу данных:

 rails g model Contact full_name:string email:string phone_number:integer address:text rake db:migrate 

Запустите спецификацию снова и альт! Это должно пройти 🙂

Мы shoulda-matchers тестирование модели, используя shoulda-matchers чтобы проверить наличие full name , address email , phone number и address . В спецификации модели контакта создайте новый блок describe :

 ***spec/models/contact_spec.rb*** describe Contact do it { is_expected.to validate_presence_of(:full_name) } it { is_expected.to validate_presence_of(:email) } it { is_expected.to validate_presence_of(:phone_number) } it { is_expected.to validate_presence_of(:address) } end 

Запустите вашу спецификацию и посмотрите, как она провалится Чтобы он прошел, перейдите к модели и реализуйте проверочный код:

 ***app/model/contact.rb*** class Contact < ActiveRecord::Base validates_presence_of :full_name, :email, :phone_number, :address end 

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

RSpec DSL Pieces

RSpec — это DSL для создания исполняемых примеров поведения кода, организованного в группы.

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

it создает пример и берет описание примера. (Пример; он has status code 400 ). Рекомендуется ограничить описание спецификации до 40 символов или менее. Если он должен быть длиннее, вам, вероятно, следует рассмотреть возможность использования context для создания «подконтекстов» блока describe .

Ожидаемый позволяет выразить ожидаемые результаты на объекте в примере. Он принимает объект или блок и используется вместе с to или not_to вместе с matcher (например, eq() , be_valid ). Несмотря на то, что имеется множество встроенных сопоставителей, такие драгоценные камни, как musta Matchers, добавляют еще больше, чтобы сделать ваши спецификации выразительными и краткими.

Спецификация контроллера

Первая спецификация контроллера будет проверять, будет ли создан новый контакт с действительными атрибутами. Откройте свой терминал и сгенерируйте контроллер:

 rails g controller Contacts 

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

Пришло время написать спецификацию для проверки действия create :

 ***spec/controllers/contacts_controller_spec.rb*** require 'rails_helper' RSpec.describe ContactsController, type: :controller do describe "POST #create" do context "with valid attributes" do it "create new contact" do post :create, contact: attributes_for(:contact) expect(Contact.count).to eq(1) end end end end 

Запустите спецификацию:

 rspec spec/controllers/contacts_controller_spec.rb 

Это не удастся, потому что у вас нет маршрута, соответствующего вашему контроллеру. Откройте файл маршрутов и поместите его в:

 ***config/routes.rb*** ... resources :contacts 

Запустите вашу спецификацию снова, и она все равно не будет работать с ошибкой The action 'create' could not be found for ContactsController .

Откройте свой контроллер и введите необходимый код для создания нового контакта.

 ***app/controllers/contacts_controller.rb*** class ContactsController < ApplicationController def new @contact = Contact.new end def create @contact = Contact.new(contact_params) respond_to do |format| if @contact.save format.html { redirect_to @contact } format.json { render :show, status: :created, location: @contact } else format.html { render :new } format.json { render json: @contact.errors, status: :unprocessable_entity} end end end private def contact_params params.require(:contact).permit(:full_name, :email, :phone_number, :address) end end 

Сохраните и запустите спецификацию еще раз, и она должна пройти.

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

 ***spec/controllers/contacts_controller_spec.rb*** context "with invalid attributes" do it "does not create a new contact" do post :create, contact: attributes_for(:invalid_contact) expect(Contact.count).to eq(0) end end end 

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

Характеристика

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

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

Откройте свой терминал или текстовый редактор и создайте папки и файл по следующему пути:

 spec/features/contacts/create_spec.rb 

Вставьте следующий код в этот файл:

 ***spec/features/contacts/create_spec.rb*** require 'rails_helper' RSpec.feature "Contact", :type => :feature do scenario "Create a new contact" do visit "/contacts/new" fill_in "Full name", :with => "My Name" fill_in "Email", :with => "[email protected]" fill_in "Phone number", :with => "123456789" fill_in "Address", :with => "34, Allen Way, OA" click_button "Create Contact" expect(page).to have_text("My Name") end end 

В приведенной выше спецификации проверяется, есть ли на странице показа текст « My Name который является значением, записанным в поле ввода full name . Запустите эту спецификацию, и она не получится.

Сначала добавьте действие show в свой контроллер:

 ***app/controllers/contacts_controller.rb def show @contact = Contact.find(params[:id]) end 

Создайте следующие файлы в представлении контактов: new.html.erb , _form.html.erb , show.html.erb и заполните их следующим кодом:

 ***app/views/contacts/_form.html.erb*** <%= form_for(@contact) do |f| %> <% if @contact.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@contact.errors.count, "error") %> prohibited this contact from being saved:</h2> <ul> <% @contact.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :full_name %><br> <%= f.text_field :full_name %> </div> <div class="field"> <%= f.label :email %><br> <%= f.text_area :email %> </div> <div class="field"> <%= f.label :phone_number %><br> <%= f.text_area :phone_number %> </div> <div class="field"> <%= f.label :address %><br> <%= f.text_area :address %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> ***app/views/contacts/new.html.erb*** <h2>Create new contact</h2> <%= render 'form' %> ***app/views/contacts/show.html.erb*** <p id="notice"><%= notice %></p> <p> <strong>Full Name:</strong> <%= @contact.full_name %> </p> <p> <strong>Email:</strong> <%= @contact.email %> </p> <p> <strong>Phone Number:</strong> <%= @contact.phone_number %> </p> <p> <strong>Address:</strong> <%= @contact.address %> </p> 

Запустите спецификацию, и она должна пройти в этот раз.

Покрытие с использованием SimpleCov

Gem SimpleCov — это инструмент анализа покрытия кода для Ruby. Вы будете использовать его в своем приложении, чтобы увидеть, сколько кода проверено. Для установки откройте Gemfile и добавьте в группу test :

 gem 'simplecov', :require => false 

Запустите bundle install .

Затем откройте ваш помощник спецификации требуют simplecov

 require 'simplecov' SimpleCov.start 

При следующем запуске спецификаций будет создана новая папка с покрытием имен. Откройте браузер и укажите: your-app-directory / coating / index.html, чтобы просмотреть статистику покрытия для вашего приложения. Вы захотите добавить папку покрытия в файл .gitignore, чтобы она не добавлялась в ваш удаленный репозиторий.

Вывод

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

  • Настройте набор тестов для своего приложения.
  • Написать модель, контроллер и технические характеристики.

Вот еще несколько ресурсов, чтобы помочь вам:

Если вы будете больше практиковаться, вы быстро освоите тестирование своего приложения на Rails.