The first line of code in a Rails app shoud be ...
By Selena Small & Michael Milewski
As part of “The Rails Camp Project”, coding with everyone at rails camp to build a simple game in Rails and ReactJS, it was time to write the first line of code. With the ability to fire up Rails and a React app clearly we could write some code? Well not exactly. The first line of code in a Rail app should be … a test of course. To run tests we prefer to use the RSpec testing framework. In todays post we setup RSpec and write that all important first feature spec to start you off on building an app.
As developers who come from a strong testing background, we are obviously not going to be teaching anyone to write code without driving the need with a test.
The idea of writing a test for functionality that does not exist sounds weird at first. This style of app development is called Test Driven Development (TDD). The idea is that new functionality is driven out by writing a test first.
More specifically, the way we like to test drive applications is to focus first on how a user might expect our app to work. This style of testing, known as Behavioural Driven Development means that we not only test functionality of individual lines of code, we also test our expected user experience.
In this experiment we were planning to build a game, with the first piece of functionality being that a user navigating to the game would be greeted with a welcome message.
Not much functionality to it really, but if that message was to change in the future for some unknown reason we would want to know about it as soon as possible. And for that reason, the first thing we would write before building the page is a test!
A BDD test can be simplified into 2 states and a function.
-
The state before the function is run
Given that the server is running in default mode
-
The function to change state
When I visit the root url of the server
-
The state after the function is run
Then assert that the welcome message is displayed as expected
So why is testing important?
And more importantly, why is test driving critical? Tests give us confidence
that certain functionality works and that changes in one place don’t break
things in other places. In fact, test driven development
, is often more
correctly refered to as test driven design
because it not only helps us to
test funtionality but also to test our design ensuring decoupled code where
changes in one place couldn’t possible break things in other places.
Many developers are tempted to just the write the code first and maybe add a test for it later on, you know, if they have time. Despite your first thought, This is not faster or more efficent! It’s much harder to write a test after the implementation and the resulting tests that are written often fool the developers writing them where they think they wrote a test but having never seen it fail can’t be sure that the test they wrote actually covered the code they implemented.
Wanting to pair with everyone at rails camp, TDD was great allowing us to chunk the work down into small pieces, even tiny pieces if need be.
Writing a failing test could be such a small test. This was critical as we had limited time with each of 36 developers at rails camp so each of them would only have time to contribute a small part. Also the only way to easily hand over code to the next developer is if there is a way to document what has been done and what we are up to. Tests play this role well.
Another major reason for wanting to write quality tests is because it also doubles as clear documentation. Theoretically, a new developer coming along should be able to read existing tests and gather an understanding of precisely how the system currently works.
Since we used Rails for the backend, we went with the well-known RSpec testing framework and our next pair, Matt Patterson, was up for the job of helping us add the framework so we could move forward.
Commit 7af2112
Author: Matt Patterson <mattpatterson94@users.noreply.github.com>
Date: Sat Nov 24 15:22:19 2018 +1100
Add rspec to gemfile and initialize
Co-authored-by: Selena Small <SelenaSmall@users.noreply.github.com>
Co-authored-by: Michael Milewski <saramic@users.noreply.github.com>
Commit 05c8c9b
Author: Matt Patterson <mattpatterson94@users.noreply.github.com>
Date: Sat Nov 24 16:07:38 2018 +1100
Configure tests to use foreman and capybara.
Co-authored-by: Michael Milewski <saramic@gmail.com>
Co-authored-by: Selena Small <selenawiththetattoo@gmail.com>
After Matt helped us with that first test we asked him some questions on the experience, starting off with how he found it.
5 minutes with Matt
Q: How did you find the pairing/testing experience?
A: It was nice. Are you teachers?
Selena: No Matt, we have no credibility as teachers [laugh] but we’re trying to get some!
Q: Do you write code outside of work? Are you working on interesting side projects?
A: Yeah at home I play around with all sorts of tech. I even have a small torrent server setup for my mum up in Queensland. It runs on port 9091. Locally I run a hydroponics setup with my RasPi, for my um .. ‘herbs.’ Oh shit did I just say that? off the record (laughter…)
note: that last comment was off the record guys…
Matt explored the ability to see if he could actually run the RSpec tests from our Procfile. This would be a Procfile task that could startup the server and run the RSpec tests. Cool idea. Unfortunately, in our short time together we did not manage to make it possible but we certainly gave it a try!
The idea was to have a Foreman Procfile which would fire up the test server and run the tests if they are successfull. In the end we went for the more traditional approach - running our server setup with Foreman in one shell and running the tests in a second shell with another command.
Not only did we teach him a few things, Matt also taught us a new shortcut for VI!
d/<match>
This allows you to delete from the cursor to whatever
Lolcommits
Sometimes you need a couple of lolcommits to get one that actually works…
3rd time the charm
And a second commit for fun
Next time
Now that we have everything setup and a failing test, clearly next post of “The Rails Camp Project” will finally write some code? No? well we hope you join us next time to find out!
Resources
- more on Given/When/Then
- levels of learning
Authored By:
Selena Small & Michael Milewski