Эта статья была рецензирована Томом Паркином . Спасибо всем рецензентам 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.