Skip to content

Instantly share code, notes, and snippets.

@ElMassimo
Last active November 24, 2020 12:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ElMassimo/2cbe1a39b20cbe8ca78efe2a65fd7e88 to your computer and use it in GitHub Desktop.
Save ElMassimo/2cbe1a39b20cbe8ca78efe2a65fd7e88 to your computer and use it in GitHub Desktop.
Ruby Yagi - Introduction to Rails testing with RSpec and Capybara - With Test Helpers
require 'rails_helper'
RSpec.describe 'create bookmark', type: :system, test_helpers: [:bookmarks] do
before { visit bookmarks_path }
scenario 'empty title and url' do
bookmarks.add(title: '', url: '')
bookmarks.should.have_error("Title can't be blank")
bookmarks.should_not.have_bookmark('Ruby Yagi')
end
scenario 'valid title and url' do
bookmarks.add(url: 'https://rubyyagi.com', title: 'Ruby Yagi')
bookmarks.should.have_bookmark('Ruby Yagi')
end
end
require 'rails_helper'
RSpec.describe 'update bookmark', type: :system, test_helpers: [:bookmarks] do
let!(:bookmark) { Bookmark.create(url: 'https://rubyyagi.com', title: 'Ruby Yagi') }
before { visit bookmarks_path }
scenario 'empty title and url' do
bookmarks.edit('Ruby Yagi', with: { title: '', url: '' })
bookmarks.should.have_error("Title can't be blank")
# The bookmark title should be unchanged
expect(bookmark.reload.title).to eq('Ruby Yagi')
end
scenario 'valid title and url' do
bookmarks.edit('Ruby Yagi', with: { title: 'Fluffy', url: 'https://fluffy.es' })
bookmarks.should_no_longer.have_bookmark('Ruby Yagi')
bookmarks.should_now.have_bookmark('Fluffy')
end
end
require 'rails_helper'
RSpec.describe 'delete bookmark', type: :system, test_helpers: [:bookmarks] do
let!(:bookmark) { Bookmark.create(url: 'https://rubyyagi.com', title: 'Ruby Yagi') }
before { visit bookmarks_path }
scenario 'removing an existing bookmark' do
bookmarks.delete('Ruby Yagi')
bookmarks.should_no_longer.have_bookmark('Ruby Yagi')
expect(Bookmark.count).to eq 0
end
end
class BookmarksTestHelper < Capybara::TestHelper
aliases(
error_summary: '#error_explanation',
save_button: [:button, type: 'submit'],
)
def bookmark_by_title(title)
find(:table_row, { 'Title' => title })
end
def add(attrs)
click_link('New Bookmark')
save_bookmark(attrs)
end
def edit(title, with:)
bookmark_by_title(title).click_link('Edit')
save_bookmark(with)
end
def delete(title)
accept_confirm { bookmark_by_title(title).click_link('Destroy') }
end
def save_bookmark(attrs)
fill_in 'Title', with: attrs[:title]
fill_in 'Url', with: attrs[:url]
save_button.click
end
def have_bookmark(title)
have(:table_row, { 'Title' => title })
end
def have_error(message)
have(:error_summary, message)
end
end

Notice how we make the test more robust by checking that the bookmarks are being displayed in the index page with the proper title.

Also, we don't click Edit or Destroy anywhere in the page, we instead restrict these actions to be inside the bookmark we expect to find in the page.

This subtle difference is very important to prevent flaky tests and false positives.

A more complete example could abstract the common functionality into a TableTestHelper or FormTestHelper, reducing the amount of duplication when we test similar CRUDs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment