In my last post I discussed the importance of RSpec and test-driven development (TDD) in evaluating Ruby code at the controller and model levels. We write tests to refactor our code, to prevent human error when developing sexy, dynamic web applications, to draft products for white labeling, and to offer guidance to future developers and collaborators of our code.
TDD is great because it ensures our models and controllers align with the overarching goals of our application — that these components communicate with each other and perform the necessary functions to transform our sexy app into a full-blown religious experience for our end user. (Yes – I said it).
But why, then, is testing such a laborious task for programmers? Like doing laundry, testing seems to evoke either pious adoration — something resembling Christianity in 17th c. New England — or vehement hisses to writing even the smallest of tests.
Before elaborating on the above — and the debate surrounding whether TDD has merit at all in the real world — I propose first an exercise in shoshin. Just go with me here.
Throw everything you know about testing in the metaphorical garburator. Wipe those Foucault college midterms and impromptu coding quizzes — thank you Flatiron! — from memory. Relax and get comfortable with TDD; heck, order-in a 12″ pie from Roberta’s and spend this Friday getting to know her better. She’s not going anywhere.
It’s important to understand testing isn’t magic — it’s not the wingardium leviosa! of spells — enabling your program to somehow run on your command. When we write tests, we are in the driver’s seat: we control our application’s engine. We think of testing as the Sparknotes of our application, offering a bit of guidance to our future self as we refactor — and to future developers who fork our code and use our Specs as Cliffnotes under the hood. As we know from High School: everybody loves Sparknotes.
A Brief Ethnographic Survey of Testing
Exploring this testing philosophy a bit deeper, I began conducting a little ethnographic surveying of my own. Reaching out to a few developer friends beyond the walls of Flatiron, I sought the hard-boiled truth to testing. Who tests? Is testing a thing? Is what I’m learning actually important to the end goal of being a ferocious femme programmer? Give me the sparknotes answer to my sparknotes metaphor!
What I discovered was astonishing: testing, it seems, is a pretty controversial topic, meriting a kind of Jerry Springer retaliation from all sides of the conversation. Never before had I encountered a topic so closely resembling an episode of Maury. And interestingly, everyone offered their opinion to why testing was either so good or so bad. From one side: TDD or die. From the other: “TDD is hocus — criminal!” – this guy.
Different Applications of Testing
As we venture deeper into full-stack development at Flatiron, I began to wonder how we might test user interaction across applications. After all, is not our user the end-goal of everything we do as technophile humanists? Alas — how do we know our user is interacting with our application in the way s/he is supposed to?
Enter Capybara. Capybara is a gem that gives us a bunch of methods that simulates how a user interacts with our Rails application. Capybara talks with many different drivers to execute our tests through the same clean and simple interface. Capybara is sometimes referred to as End-To-End testing because it tests higher-level tests while flexing the entire stack of our application (our Models, Views and Controllers).
RSpec and Capybara
This left me questioning the difference between RSpec and Capybara. Behold another metaphor: imagine RSpec as that austere, extremely-French, French teacher you had in Grade 10. Yes – that one, who quizzed you on verb conjugations, keeling over as you occasionally forgot the translations to seminal cultural tokens like “aujourd’hui, maman est morte.” By contrast, Capybara is that gym teacher who once convinced you that line-dancing was an appropriate way to spend an hour of your time. The image of her slapping her hands together as I fell out of electric slide formation will be forever imprinted in memory.
Whereas RSpec tests how models and controllers communicate with one another in various ways — the conjugation of verbs and their correct usage in french sentences — Capybara tests how users interact with the pages of your Rails app. Capybara methods, like clicks on a page, form interaction, finding elements on a page, and the electric slide, are examples of this. OK, maybe not the electric slide, but Capybara gives us a ton of methods to help us test really important user interactions. Peeps the Capybara cheat sheet here.
Key Benefits of Capybara (from the Capybara API)
- No setup necessary for Rails and Rack application. Works out of the box.
- Intuitive API which mimics the language an actual user would use.
- Switch the backend your tests run against from fast headless mode to an actual browser with no changes to your tests.
- Powerful synchronization features mean you never have to manually wait for asynchronous processes to complete.
To run Capybara, we must include it in the Gemfile of our rails application.
group :development, :test do gem "rspec-rails" gem "capybara" end
We group RSpec and Capybara under the development testing suite of our application because we are testing user interaction. To write our Capybara tests, we hard code sample user data to populate into our forms. By this measure, we can then test the functionality of our application.
In our testing environment, we need to first load RSpec and Capybara, configure RSpec, include Capybara in our Rails app, define the application we are testing, load the application defined in config.ru, and finally configure Capybara to test against the application we are testing. In our spec/spec_helper.rb we add the following code (as taken from Learn):
# Load RSpec and Capybara require 'rspec' require 'capybara/rspec' require 'capybara/dsl' # Configure RSpec RSpec.configure do |config| # Mixin the Capybara functionality into Rspec config.include Capybara::DSL config.order = 'default' end # Define the application we're testing def app # Load the application defined in config.ru Rack::Builder.parse_file('config.ru').first end # Configure Capybara to test against the application above. Capybara.app = app
For a more comprehensive walk-through of testing with RSpec and Capybara, check out the video below.
Capybara Cheat Sheet (from SmallFry GitHub).
How We Test Rails Applications by John Steiner