Latest August of this year I started to learn Rails. I was following the book Ruby on Rails Tutorial from Learn Enough To Be Dangerous website which uses Minitest to test their application. Truth is: I was not understanding a single line of code about those tests. So I decided to skip them and try to write it using RSpec because the syntax is way more similar to human language than others. But you may be wondering:
Well, despite the fact that this is a must-have skill for developers, writing tests help you to make sure that your code is producing the results you expect. So that being said, let's start coding!
First of all, let's create our new Rails App, type in your terminal:
rails new app_for_test -T
The command -T is to skip the generation of
Test::Unit
files and folders, which is exactly what we want because we're going to use RSpec to test our application instead of the default.Now go to your gemfile and add the RSpec gem in the development, test group:
group :development, :test do
gem 'rspec-rails'
end
Note: if you're using Rails 6 you need to write:
'gem 'rspec-rails', '~> 4.0.0.beta2'
Then in your terminal run the command:
bundle install
To set up RSpec in your app and create the Spec folder run:
rails generate rspec:install
Let's start with our model. I'll create a simple Movie table that has a title, director and rate:
rails generate model Movie title:string director:string rate:integer
Then:
rails db:migrate
Now you should have the following file in your app: spec/models/movie_spec.rb
Following the TDD(Test Driven Development) principles, we're going to build our tests and then write the code. Let's think about what kind of tests we need for Model:
In your spec/model/movie_spec.rb you will see the RSpec block where you will write your tests inside it:
RSpec.describe Movie, type: :model do
#tests go here
end
Now we will create it blocks for each behaviour we're expecting in the Movie's model. So remember to be as clear as possible when describe your tests because you need to be a good communicator and make yourself understandable not only with computers but also with people.
You may be wondering why did I upload an image, right? Well, it was on purpose so this way you will have to actually write the code instead of just copy and past and that will be really good for your muscle memory and practice with eventual typos.
Now to run your tests, type in your terminal:
rspec
The command above will run all the tests available in your entire app. When you want to run tests only in some specific files you can type:
rspec spec/some_folder/file_spec.rb
That format in our application would be:
rspec spec/models/movie_spec.rb
We just have one test file in this app so both commands will get you the same results, which in our case is: 8 examples, 8 failures and this makes sense because if you pay attention in what we expect in the tests you'll see that none of them should be valid and all of that are being valid now because we have our model's validations completely empty.
Now let's write the necessary validations to make our tests green!
In your app/models/movie.rb, write the following lines:
validates :title, presence: true, length: { in: 6..25 }
validates :director, presence: true, length: { in: 5..20 }
validates :rate, presence: true, length: { in: 1..10 }, numericality: { only_integer: true }
Now run rspec again in your terminal:
rspec
You should get: 8 examples, 0 failures.
And... That's it! You just wrote your first tests using RSpec. So if you want to keep going try to write some specs for Movies' controller now and when you feel confident with those you can search and learn how to use Capybara, FactorbyBot, and Faker to write more complex tests. You can check out this repository to get some ideas.
Good luck with your journey and HAPPY CODING!!!