Choosing appropriate tools for the job
In software development, it is easy for developers to sometimes choose tools that are not perfect for the job. This could be because maybe it made sense at that particular time, we were facing a tight deadline, we were not familiar enough with our tools, or a plethora of particular circumstances. It is always beneficial to consider alternatives.
Recently, we have encountered a few situations where using alternatives to our "default" tools improved our project code. The tools that were already in place did the job sufficiently well, but replacing them with simpler ones made more sense in these situations.
Feature specs and view specs
We had a situation where feature specs were overused, and we replaced them with view specs successfully.
In this particular project, we used rspec for each module, and feature specs for integrating the whole lot. In one case, all we were checking was that the message intended for admin users was displayed for admin users, and not regular users.
We were checking the page contents in both cases here, but feature specs actually used real web browsers in a "headless" manner, while view specs simply rendered templates.
The code was like this:
<% if current_user.admin? %> <%= @admin_message %> <% end %>
We had feature specs like these:
feature 'user notifications' do scenario 'admin message is not shown' do login_as user ... expect(page).not_to have_content(latest_admin_message) end end feature 'admin notifications' do scenario 'admin message is shown' do login_as admin ... expect(page).to have_content(latest_admin_message) end end
We replaced these with view specs:
context 'user notifications' do before do allow(user).to receive(:admin?) { false } end it 'does not show admin message' render expect(rendered).not_to have_content(latest_admin_message) end end context 'admin notifications' do before do allow(user).to receive(:admin?) { true } end it 'shows admin message' do render expect(rendered).to have_content(latest_admin_message) end end
Unit tests cannot always replace integration tests, but in this case, this was sufficient for us. In fact, this eliminated many other potential causes of failure that we were not interested in, and the view specs ran much faster.
Another important benefit of this was that it has made the specs more focused and clearer about our intentions.
VCR and Webmock
In a separate situation, the VCR gem was used to capture the remote API response where direct use of Webmock would simplify the code.
If you don't know what VCR does, it lets us "record" web responses to requests, and play it back later so we don't have to access the real remote server every time. It is extremely valuable in testing since it removes the dependency on external services. While it is no replacement for manual, real-world tests, it lets us simulate very closely.
It saves a lot of information in yaml files. This is not all, but it looks like this:
--- http_interactions: - request: method: get uri: http://example.com/api/ body: encoding: US-ASCII string: '' headers: Accept-Encoding: - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 Accept: - "*/*" User-Agent: - Ruby response: status: code: 200 message: OK
and so on.
The problem we had, was that we had tests that used recorded and then modified response files. Let's say we want to test our code against errors, like 500, or 200 with broken JSON contents. These error scenarios should be tested but they are not easy to actually record, since we usually don't (or at least we hope not to) receive a lot of malformed responses or internal server errors from remote services. In our test cases, we had modified response files (or "vcr cassettes") to suit our needs.
Instead of modifying saved response files, we simplified this by using Webmock's stub_request
:
stub_request(:any, remote_api_address).to_return { { status: 500, body: '' } }
or:
stub_request(:any, remote_api_address).to_return { { status: 200, body: 'Malformed JSON!' } }
This made our specs a lot easier to read since we did not need all the extra details VCR would save for us in these cases.
One of the major advantages of VCR is the ability to update the input files by recording the updated responses but, we were not interested in that here. This rewrite made it more focused and easier to understand the intentions.
Other gems
Similarly, we have come across situations where it made sense to replace a decorator gem with our own, simpler decorators that did less. There were also some other gems we have removed in the past, like the one that helped us with memoization.
These gems worked well, and they were very good for what they were intended for. However, it does not mean we should use third-party tools just because their functionalities cover what we need.
Summary
Every tool has its advantages and disadvantages. Every time we add a third-party tool, we are accepting all the disadvantages that come with it. Keeping the code simple and free of unnecessary complexity makes it easier to read and maintain.
We should always try to choose the simplest tools that do the job. It'll help us keep things simpler, because simpler code is always easier to work with.
Popular Articles by Our Team
Our expert team of designers and developers love what the do and enjoy sharing their knowledge with the world.
-
The Benefits of Ruby on Rails
-
Heroku Forcing Password Resets as GitHub Investigation Continues
-
How to Maximise your ROI with a Custom Application Built in Sa...
We Hire Only the Best
reinteractive is Australia’s largest dedicated Ruby on Rails development company. We don’t cut corners and we know what we are doing.
We are an organisation made up of amazing individuals and we take pride in our team. We are 100% remote work enabling us to choose the best talent no matter which part of the country they live in. reinteractive is dedicated to making it a great place for any developer to work.
Free Community Workshops
We created the Ruby on Rails InstallFest and Ruby on Rails Development Hub to help introduce new people to software development and to help existing developers hone their skills. These workshops provide invaluable mentorship to train developers, addressing key skills shortages in the industry. Software development is a great career choice for all ages and these events help you get started and skilled up.