KatPadi's Point

RSpec Adventures

RSpec is an awesome tool for behaviour-driven testing. It’s mostly used in test driven development (“TDD”), where the developer writes the test based on what the application should do, and then creates the program to accomplish the goals of the test.

At first, I found this tedious because it means extra work for me (the developer). But in the long run, it actually saves time in the process because I can easily tell whether the program is functioning properly.

There are many types of specs but for Rails to support functions, the specs need to have the corresponding metadata :type value:

  • Model specs: type: :model
  • Controller specs: type: :controller
  • Request specs: type: :request
  • Feature specs: type: :feature
  • View specs: type: :view
  • Helper specs: type: :helper
  • Mailer specs: type: :mailer
  • Routing specs: type: :routing

I haven’t tried doing Mailer and Routing specs but among the other types, Feature specs testing is my favorite because it simulates the application externally via the web pages. It’s like automating the user experience and it feels like magic because the web browser is moving on its own. Because of the “real user” interaction magic, feature specs require a special gem called Capybara.

Sample RSpec test file:

require 'rails_helper'

describe 'MyAwesomeTasks' do
  let!(:dummy_task) { create :my_awesome_task }

  describe "Tasks Form" do
    subject { page }
    it { is_expected.to have_field('my_awesome_task[title]') }
    it { is_expected.to have_field('my_awesome_task[description]') }
    it { is_expected.to have_field('my_awesome_task[content]') }
    it { is_expected.to have_button('Add Task') }
  end
  
  describe 'Method #edit' do
    it 'has clickable link' do
      expect(page)
        .to have_selector("a#my_awesome_task#{dummy_task.id}")
    end
    it 'actually works', js: true do
      page.find("a#my_awesome_task#{dummy_task.id}").click
      wait_for_ajax
      expect(page).to have_selector('#my_modal', visible: true)
      fill_in 'my_awesome_task[description]', with: 'kakorrhaphiophobia'
      click_button 'Save'
      wait_for_ajax
      expect(page)
        .to have_text('kakorrhaphiophobia')
    end
  end
end

Sample Factory file:

FactoryGirl.define do
  factory :my_awesome_task do
    sequence(:title) do |n|
      "#{Faker::Lorem.word}#{n}"
    end
    description 'Oxter'
    content 'Buy milk at 5pm'
    updated_at Time.now
  end
end

Another cool thing about this whole RSpec thingy is the Factory concept. Factories produce dummy data for tests. In my sample file, FactoryGirl is used. It basically just sets up test data but it creates Ruby objects as test data.

These are just basic tests that I can show but I’m sure I can do much more with it.

Although making tests requires additional time and effort, it’s a very good practice that will help devs maintain codes long-term. Plus, you won’t notice its “burden” because creating RSpec adventures are really enjoyable.

Leave a Reply

Your email address will not be published. Required fields are marked *