Chapter I - Introduction to RSpec
(avr. time for this chapter: 1 day)
Testing is a crucial part of software development. In the Ruby on Rails ecosystem, RSpec is one of the most popular testing frameworks. It provides a behavior-driven development (BDD) approach that makes tests readable and maintainable.
In this chapter, the objective is to understand the basics of RSpec, how to set it up in your ebook application, and how to write your first tests.
RSpec Setup
Before writing tests, you need to set up RSpec in your Rails application.
Steps to implement:
- Add the
rspec-railsgem to your Gemfile (in the:developmentand:testgroups) - Run
bundle install - Initialize RSpec with
rails generate rspec:install - Understand the folder structure created:
spec/- main folder for all testsspec/spec_helper.rb- RSpec configurationspec/rails_helper.rb- Rails-specific configuration.rspec- command line options
Reference: RSpec Rails Documentation
Basic Test Structure
Understand the anatomy of an RSpec test file:
describeblocks - group related testscontextblocks - describe different scenariositblocks - individual test casesexpect- make assertions
Steps to implement:
- Generate the spec file for your Ebook model:
rails generate rspec:model Ebook - Open
spec/models/ebook_spec.rband examine the generated structure - Write your first test checking if the model can be instantiated
- Run tests with
bundle exec rspec
RSpec Matchers
Matchers are used to define expected outcomes. Practice with your Ebook and User models.
Steps to implement:
- Practice using equality matchers:
eq,eql,equal,be - Example:
expect(ebook.status).to eq('draft') - Practice using comparison matchers:
be >,be <,be_between - Example:
expect(ebook.price).to be > 0 - Practice using truthiness matchers:
be_truthy,be_falsy,be_nil - Example:
expect(user.enabled?).to be_truthy - Practice using collection matchers:
include,match_array,contain_exactly - Example:
expect(Ebook.statuses.keys).to include('draft', 'pending', 'live') - Practice using predicate matchers:
be_empty,be_valid - Example:
expect(ebook).to be_valid
Reference: RSpec Built-in Matchers
Hooks: before and after
Hooks allow you to run code before or after tests.
Steps to implement:
- Use
before(:each)to set up an ebook for each test:before(:each) do @ebook = Ebook.new(title: "Ruby Guide", price: 19.99) end - Use
before(:all)to set up data once for all tests in a group - Understand when to use
afterhooks for cleanup - Practice using
letandlet!for lazy and eager evaluation:let(:user) { User.create(name: "John", email: "john@example.com") } let(:ebook) { Ebook.create(title: "Rails Tutorial", seller: user) }
Exercise
Apply these concepts to your ebook application:
- Set up RSpec in your ebook application (if not already done)
- Generate spec files for your existing models:
rails generate rspec:model Ebookrails generate rspec:model User- Write basic model specs for your
Ebookmodel: - Test that an ebook can be created with valid attributes (title, price, seller)
- Test that an ebook without a title is invalid
- Test the status enum values (Draft, Pending, Live)
- Write basic model specs for your
Usermodel: - Test that a user can be created with name and email
- Test the enable/disable status functionality