Writing automated tests is THE thing to learn as a Developer Newbie
Learn rspec for Ruby on Rails
So, you’ve just caught the basics of coding. Maybe, like me, you have finished the coding bootcamp of Le Wagon or had another amazing experience making your first steps as a developer. After learning the basics, there is a question that might arise: What shall I learn next? The answer is crystal clear: Learn to write tests!
Why automated testing?
Why is that so clear? I am 100% sure that during your first coding experience, you ran into your first bugs. I am also sure that at least once it happened to you that you created a new feature, forgot to check its impact on your existing code, and — oops! — ran into bugs again. Or you implemented changes, opened localhost, and checked your application over and over….losing loads of time testing MANUALLY.
Now scale this up to a real running application where you implement a new feature and are about to release it. What happens without automated tests?
Best case: You test manually hour after hour, find and fix your bugs before you go into production.
Bad case: You go to production, find a bug right away, and spend the night fixing it.
WORST case: You go to production and next morning you get alerted by your customers that they are not able to buy your product due to a critical bug.
Even the best case doesn’t sound very appealing, right? This is why I strongly recommend you to learn how to write automated tests.
RSpec to test your Rails App
Rails comes with Minitests which is a nice tool. However, I would like to give you some insights into Rspec. In my opinion it has the advantage of writing code with a natural English language syntax. Moreover, RSpec is widely used in Rails projects and it’s easy to find answers on Stack Overflow.
But obviously, opinions differ.
RSpec Set up and usage
To set Rspec up, just follow their github installation guide . In addition to Rspec, I also recommend you to install the gem “shoulda-matchers” which supplies simple one-line-codes to test the most common test cases.
Ideally, you write your tests first and then implement your features to then keep testing it. That’s the typical Test Driven Development (TDD) approach. Here, I will explain it the other way around as it is easier for a reader to follow the logic. And also, in practice, it is common that tests are written after the main code is implemented. Often, when you start as a junior, you are asked to write tests of an existing code. It helps you to get an understanding of the application.
RSpec: Test the basics of your models
Suppose that you are building an application for booking hotel rooms. You have a Model with Hotels that have many Rooms and Rooms have many Bookings. Within those models you also have some validations. The models could look like that:
Now let’s write the basics specs (tests) of the Hotel model:
- Create a hotel_spec.rb file in your spec/models folder
There is also a generator that creates rspec files automatically:
rails generate rspec:model hotel
2. Write your basic tests using the shoulda matchers
Looks nice but what’s up with that syntax? Let’s walk through it step by step:
Line 1: Make sure you require the rails_helper where spec_helper is required. spec_helper is automatically generated when you install the rspec gem
Line 3: Indicates what you are testing: Here we are focusing on the Model Hotel
Line 4–9:
- it {}: is a RSpec method which describes the specifications of what you want to test. Within the it you find your test case. It reads almost like plain english, don’t you think?
- is_expected.to: another RSpec method that tells us what we expect the code to do. Pretty much plain english again.
- ‘have_many’, ‘validate_presence_of’, ‘validate_length_of’ are active model matchers that indicate with what your data has to match. These are simple one_line statements that we can use thanks to Shoulda Matchers. Also the following methods such as ‘dependent’, ‘through’, ‘is_at_most’ are provided to us by Should Matchers. For all options check their documentation.
Now, you just have to go to your console and run ‘rspec’. You will get the results of your tests.
Rspec: Test the methods of your models
Imagine your Room Model has a price. And there is a method “expensive?” which defines if a room is expensive with true or false:
First you need to create the room_spec.rb file, as shown before. Then, you can test the method:
Let’s go through it again step by step. In general, you can see that 3 different scenarios are being checked. One with where the price is higher than 50, exactly 50 and lower than 50:
- Line 4: before: describes activities that are being executed before each of the tests. In this case, that is the assignment of the price to a room. The room is being represented by the subject. It refers to the variable of the tested Model, which is in this scenario a room. The subject could be understood as if we had written something like the code below (please note: it is not exactly what happens, but you get the idea). For the rest of the tests room_one is now the subject on which we assign a different price.
hotel_one = Hotel.create(name: 'name')
room_one = Room.create(hotel: hotel_one, name:'name', max_hosts: 3)
- Line 6: describe(): Again — as almost in plain english — it describes the method to be tested. In this case, a # is used because it is referring to an instance method. If it was a class method, you would use a dot (.) instead of the #
- Line 7/12/17: context(): is describing the scenarios that will be tested
- Line 6/11/17: let(): is a idiomatic way to define variables in rspecs. In order to test these scenarios, the price needs to be adapted to the described scenario in the context. Thus, the test values for the price are being set thanks to the ‘let’. → :price is now representing the price we set in line 4 within the ‘before’. It is as we would have written something like this:
room_one.price = 56
- Line 8/13/18: Not_to be_expensive: Built in Rspec Matchers to test the expectation of the scenario. In this case, since we are testing for booleans, the not_to be_expensive can be directly used. For all built in matcher see the documentation.
Now again, run ‘rspec’ in your terminal and check whether your tests are passing. You will see how does little green lines will enlighten your day!
Further Resources
Of course, there are tons of other things that you can test with Rspec. I recommend you to have a look at some of these resources:
- Full documentation and good video tutorials on rspec
- Better specs for tips and best practice for rspec
- Factory Girl to create test data
❤ Stay tuned for more articles by the amazing dev-team of luvotels ❤