Now, that you know what tests are, let's discuss the different types of tests!
In your Rails app, you have models, views, and controllers. It should be no surprise that tests can be written for models, views, and controllers.
As you learned in the previous section, tests are used to verify that your code is working as expected. So, a couple things we can test right off the bat are that a tree should have certain associations and validations. Let's start by writing some model tests also known as unit tests! This link might come in handy to remember singular vs. plural Rails conventions: https://alexander-clark.com/blog/rails-conventions-singular-or-plural/
Steps
Step 1
First, create a orange model. By creating the model, a spec file will also be added to the models folder of the spec folder. Type this in the terminal:
rails generate model Orange
Then, run the migration to actually create the oranges table.
bundle exec rake db:migrate
Step 2
Then, run rspec.
bundle exec rspec
You will see a report with one pending test. When you generated your Orange model, RSpec also generated a matching spec file. Copy the test below into spec/models/orange_spec.rb and run 'bundle exec rspec' on the terminal again.
RSpec.describe Orange, :type => :modeldo
context 'ActiveRecord associations'do
it 'belongs to tree'do
expect(Orange.reflect_on_association(:tree).macro).to be (:belongs_to)
endendend
Run 'bundle exec rspec'. This test fails! Let's add an associaton to our model. Add a belongs_to association to orange.rb:
Run 'bundle exec rspec' and now you should see one passing test! That's an example of an association test. Let's modify that test to fail. Then, run 'bundle exec rspec' and see what happens. Cool! Let's revert back to the passing test.
Step 3
Now let's write a has_many association test for the relationship between the Tree model and the Orange model! (hint: this doesn't exist yet so you'll have to create the model and migrate!)
On to controller tests! Just like the Orange model, you will create the OrangesController, which will also create spec files in the /spec/controllers folder of your app.
Step 4
First, create the oranges controller and relevant spec files by typing this in the terminal:
rails generate controller Oranges
Step 5
Then, run RSpec.
bundle exec rspec
You should see a report with some passing tests but those are just the model tests you wrote. So, let's add some controller tests! Copy the below test, paste it into the oranges controller spec file, create the relevant view files and then run 'bundle exec rspec' on the terminal again.
RSpec.describe OrangesControllerdo
context '#index'do
it "renders the index view"do
get :index
expect(response).to render_template("index")
end
it "renders html"do
process :index, method: :get
expect(response.content_type).to eq "text/html"endendend
You should see two failing tests. Hint: You'll need to add a route, index action, and a view. Not sure where to start? Read the errors in your failing tests for a hint. Run 'bundle exec rspec' after each change until both tests pass.
Note: as you write the controller tests, you may be prompted to install a missing gem called 'rails-controller-testing' to use the assert_template method. If prompted, please add it to your Gemfile and do a bundle install!
Step 6
Now, write another controller test for the new action (hint: you might need to look up what a mock is).
Step 7
Last but not least: view tests! Below is an short snippet of a possible Orange show HTML page you can create in your app:
<br>
Orange title: <%=@orange.name %><br><br>
Orange tree id: <%=@orange.tree_id %><br>
So, based on the orange you create, the show page should render HTML with the orange's name and tree id. Let's verify that with a few tests.
First, create a views folder in the spec folder. Then, create an oranges folder in the views folder. Lastly, create an oranges view spec file in the oranges folder. Type these commands in the terminal:
mkdir spec/views
mkdir spec/views/oranges
cd spec/views/oranges
touch show.html.erb_spec.rb
Step 8
Change directory back to the root directory of your app. Then, run rspec.
cd ../../..
bundle exec rspec
You should see a report with some passing tests but those are just the model and controller tests you wrote. So, let's add some view tests!
We're going to up the ante a bit here and NOT show you an example :) Google and StackOverflow are your friends here!
Once, you have written some passing view tests, take a deep breath and pat yourself on the back! Testing is hard. But, it's critical in making sure software is stable and functional.
So, I fibbed a little bit. There are more types of tests than just MVC tests. One of these other important tests is called an integration test. As the name indicates, it tries to assess how well multiple components in an app interact and is written in Rails as a feature spec test. Typically, these tests simulate a user and a user's actions to test end-to-end functionality.
Here's a diagram from Thoughtbot that may help with understanding how integration tests fit in:
Capybara is a common framework used to write integration tests in Rails. It integrates nicely with RSpec such that you can use the same kind of test language to write integration tests.
As an added bonus for this section, write an integration test :)