DEV Community

K-Sato
K-Sato

Posted on

Rspec Basics(1)

Table of contents

  1. What is Rspec?
  2. How to install Rspec on your RoR applications?
  3. Basic Structure

What is Rspec?

RSpec is a Behaviour-Driven Development tool for Ruby programmers. BDD is an approach to software development that combines Test-Driven Development, Domain Driven Design, and Acceptance Test-Driven Planning.

How to install Rspec on your RoR applications?

You have to add rspec-rails to both the :development and :test groups in the Gemfile.

group :develop, :test do gem 'rspec-rails' end 
Enter fullscreen mode Exit fullscreen mode

You can download and install it by running the line below.

$ bundle install 
Enter fullscreen mode Exit fullscreen mode

To initialize spec/ directory(where specs will reside), You can do so by running the command below.

$ rails g rspec:install 
Enter fullscreen mode Exit fullscreen mode

This will add the following files which are used for configuration.

  • .rspec
  • spec/spec_helper.rb
  • spec/rails_helper.rb

You can run your specs (execute spec files) by running rspec command.

$ bundle exec rspec 
Enter fullscreen mode Exit fullscreen mode

By default, the command above will run all _spec.rb files in the spec directory.
You can run only a subset of these specs by specifying the file path like the example below.

# Run only model specs $ bundle exec rspec spec/models  # Run only specs for PostController $ bundle exec rspec spec/controllers/posts_controller_spec.rb  #Run only spec on line 8 of PostController $ bundle exec rspec spec/controllers/posts_controller_spec.rb:8 
Enter fullscreen mode Exit fullscreen mode

If you want to use classes that are defined in your application, don't forget to add require 'rails_helper' to each file.

require 'rails_helper' describe 'Post' do it 'tests type matchers' do ins = Post.create(title: 'title', content: 'content') end end 
Enter fullscreen mode Exit fullscreen mode

Basic Structure

To show the basic structure of Rspec with real examples, I created a simple CRUD RoR application with scaffold command. You can create the same application by running the code below.

$ rails g scaffold Post title:string content:text 
Enter fullscreen mode Exit fullscreen mode

Describe

The word describe is used to define an example group which is the Rspec way of saying a collection of tests. describe takes a class name and/or string argument. You can define an example group like the code below.

describe Post do #tests end 
Enter fullscreen mode Exit fullscreen mode

It

The word it is another RSpec keyword which is used to define an example. An example is basically a test or a test case. You can define an example like the code below.

describe Post do it 'test case' do #test content end end 
Enter fullscreen mode Exit fullscreen mode

Expect & to/not_to

The expect keyword is used to define an expectation in Rspec. The to keyword is also used as part of expect statements. You can also use not_to keyword when you want the expectation to be false.

describe 'Post' do it 'test case' do value = 1 expect(value).to eq(1) end end 
Enter fullscreen mode Exit fullscreen mode

The eq keyword is one of Rspec matchers . Each matcher can be used with expect(..).to or expect(..).not_to to define positive and negative expectations respectively on an object.

Context

The context keyword is just an alias method of describe that means there is no functional difference between these two methods. However, there is a contextual difference that makes your tests more understandable by using both of them.
Generally speaking, describe is used to separate sets of tests based on methods or behavior that is being tested, whereas context is used to separate specs based on conditions.

describe 'Post' do context 'name == Jim' do #tests end context 'name == John' do #tests end end 
Enter fullscreen mode Exit fullscreen mode

Matchers

We used a matcher eq in the above example. Here, I will introduce other types of matchers.

Equality matchers

Rspec has several different methods for handling equality.

require 'rails_helper' describe 'Post' do it 'tests equality matchers' do a = 'value' b = 'value' expect(a).not_to equal(b) # object identity - a and b refer to the same object expect(a).to eql(b) # object equivalence - a and b have the same value expect(a).to be == b # object equivalence - a and b have the same value with type conversions end end 
Enter fullscreen mode Exit fullscreen mode

Comparison matchers

RSpec provides a number of matchers that are based on Ruby's built-in operators. These can be used for generalized comparison of values. I'll introduce some of many matchers that I frequently use. For further information regarding this topic, check Relish.

require 'rails_helper' describe 'Post' do it 'tests comparison matchers' do a = 1 b = 2 expect(a).to be > 0 expect(a).to be < b expect(a).to be >= 0 expect(a).to be <= b expect(a).to be == 1 end end 
Enter fullscreen mode Exit fullscreen mode

Predicate matchers

Ruby objects commonly provide predicate methods like zero?, empty? and has_key?. You can use those methods in Rspec by Simply prefixing the method with be_ and remove the question mark.

require 'rails_helper' describe 'Post' do it 'tests predicate matchers' do a = 1 arry = [] hash = { key: 'value' } expect(a).not_to be_zero expect(arry).to be_empty expect(hash).to have_key(:key) end end 
Enter fullscreen mode Exit fullscreen mode

Type matchers

You can test the type or class of objects in Rspec by using be_kind_of(), be_instance_of().

require 'rails_helper' describe 'Post' do it 'tests type matchers' do str = 'string' ins = Post.create(title: 'title', content: 'content') expect(str).to be_kind_of(String) # same as expect(obj).to be_kind_of(type) expect(str).to be_a_kind_of(String) # same as expect(obj).to be_kind_of(type) expect(str).to be_a(String) # same as expect(obj).to be_kind_of(type) expect(str).to be_an(String) # same as expect(obj).to be_kind_of(type) expect(ins).to be_instance_of(Post) expect(ins).to be_an_instance_of(Post) # same as expect(obj).to be_instance_of(type) end end 
Enter fullscreen mode Exit fullscreen mode

Be matchers

There are several related be matchers.

require 'rails_helper' describe 'Post' do it 'tests be matchers' do obj1 = true obj2 = false obj3 = nil expect(obj1).to be_truthy expect(obj1).to be #It is the same as be_truthy expect(obj2).to be_falsey expect(obj3).to be_nil end end 
Enter fullscreen mode Exit fullscreen mode

Include matchers

You can use the include matcher to specify that a collection includes one or more expected objects.

require 'rails_helper' describe 'Post' do it 'tests include matchers' do str = 'String' arr = [0,1,2] expect(str).to include('S') expect(str).to include('St', 'r') expect(str).not_to include('A') expect(arr).to include(0) expect(arr).to include(0, 1) expect(arr).not_to include(9) expect(arr).to include(be_odd.and be < 10) expect(arr).to include(a_kind_of(Integer)) end end 
Enter fullscreen mode Exit fullscreen mode

Expect error

Use the raise_error matcher to specify that a block of code raises an error.

describe 'Post' do it 'tests errors' do expect { raise "boom" }.to raise_error expect { raise "boom" }.to raise_error(RuntimeError) expect { raise "boom" }.to raise_error("boom") expect { raise "boom" }.to raise_error(/boom/) expect { raise "boom" }.to raise_error(RuntimeError, "boom") end end 
Enter fullscreen mode Exit fullscreen mode

Respond_to matchers

Use the respond_to matcher to specify details of an object's interface.

describe 'Post' do it 'tests respond_to matchers' do str = 'String' expect(str).to respond_to(:split) expect(str).to respond_to(:to_i, :to_sym) end end 
Enter fullscreen mode Exit fullscreen mode

More matchers are listed on Relish.
The original post is posted on my blog

Top comments (1)

Collapse
 
meave9786 profile image
meave9786

Just visit this wonderfully post here how to open crdownload file this is very use full for all of you.