Konfiguracja projektu Ruby on Rails 6, Rspec, Capybara, FactoryBot, Database Cleaner

Artykuł ten będzie prostym i szybkim poradnikiem opisującym jak utworzyć nowy projekt w Rails 6 oraz przygotować go do pisania kodu w duchu metod BDD / TDD. Zakładam, że każdy wie do czego służą poszczególne biblioteki.

Utworzenie nowego projektu

W pierwszej kolejności – tworzymy nowy projekt, pomijając domyślnie generowane testy przez Rails:

rails new demo -d=mysql -T

Dopisujemy niezbędne biblioteki w sekcji „group :development, :test” pliku Gemfile.

group :development, :test do
  [...]
  gem 'database_cleaner'
  gem 'factory_bot_rails'
  gem 'faker'
  gem 'rspec-rails'
  gem 'capybara'
end

Instalujemy biblioteki:

bundle install

Uruchomienie Rspec

Generujemy pliki konfiguracyjne Rspec:

rails generate rspec:install

Tworzymy katalog na pliki konfiguracyjne pozostałych komponentów:

mkdir spec/support

Następnie edytujemy plik spec/rails_helper.rb i usuwamy komentarz z linii:

Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

Spowoduje to automatyczne załadowanie plików konfiguracyjnych które będą znajdować się w pliku spec/support.

Uruchomienie Capybara

Tworzymy plik spec/support/capybara.rb o treści:

require 'capybara'

Uruchomienie Factory Bot

Tworzymy plik spec/support/factory_bot.rb o treści:

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

Uruchomienie Database Cleaner

Tworzymy plik spec/support/database_cleaner.rb o treści:

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.clean_with :truncation, except: %w(ar_internal_metadata)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

Następnie – zmieniamy wartość config.use_transactional_fixtures w pliku spec/rails_helper.rb na false:

RSpec.configure do |config|
  [..]
  config.use_transactional_fixtures = false

Sprawdzenie działania

Przejdziemy teraz do napisania pierwszego testu, który sprawdzi czy aplikacja uruchamia się poprawnie.

Tworzymy katalog na testy funkcjonalne:

mkdir spec/features

i umieszczamy w nim plik o nazwie hello_spec.rb o treści:

require "rails_helper"

describe "Hello", type: :feature do

  it "Hello" do
    visit root_path
    expect(page.status_code).to eq(200)
  end

end

Następnie uzupełniamy konfigurację bazy danych w pliku config/database.yml i tworzymy niezbędne bazy poleceniem:

rails db:create

Teraz możemy uruchomić testy:

rspec

Testy powinny zakończyć się błędem:

Failures:

  1) Hello Hello
     Failure/Error: visit root_path

     NameError: undefined local variable or method `root_path' for #<RSpec::ExampleGroups::Hello:0x007f99535687d8> # ./spec/features/hello_spec.rb:6:in `block (2 levels) in <top (required)>'

Finished in 0.07546 seconds (files took 3.63 seconds to load)
1 example, 1 failure

Failed examples:
rspec ./spec/features/hello_spec.rb:5 # Hello Hello

Następnie, edytujemy plik config/routes.rb i dopisujemy:

root to: proc { [200, {}, ['']] }

Kolejne uruchomienie testów powinno zakończyć się powodzeniem:

Finished in 0.03854 seconds (files took 3.19 seconds to load)
1 example, 0 failures