Over the years I've helped over 10,000 engineers hone their craft. Engineers have used my books, articles, and talks to improve their technical skills, get promotions, change jobs, and ship their products faster.

Bring Ruby VCR to Javascript testing with Capybara and puffing-billy

Let’s say you are writing an application in Ruby. You are probably talking to every API under the sun and are happily writing tests to make sure your code isn’t failing.

Because you don’t want to rely on 3rd parties or an internet connection to make your tests pass or fail you mock everything with let’s say, Webmock. This also makes your tests much much faster. After all even the fastest internet is much slower than the processor talking to its memory.

If you’re too lazy to mock out every API under the sun, you might use VCR to record requests and play them back later. The main advantage being, you don’t have to worry about meticulously reimplementing everything, and you can nuke the recordings at any time to make sure your code still works against the real API.

The idea was great – spin up a web proxy, tell your headless browser to use it, when your code makes a request it will go through the proxy, which will try to use a Webmock to handle it, otherwise pass it on to the vast internet.

But who wants to mock everything out manually?

Over the past few weeks I set upon the task of fixing this problem and restoring sanity to my life. Good tests are transparent to the application and I’ll be damned if I use any of the suggested solutions on the internet like “Well you just put a switch in your code that knows if you’re in a test and then doesn’t talk to Stripe”

I added the ability for puffing-billy to behave like it was VCR, but for your browser. When a request is made, it gets cached. The cache is then persisted between sessions, and requests are played back to the browser as needed.

It’s not as sophisticated as VCR just yet, but it gets the job done and my test runtime has gone from 3 minutes to just under a minute. That’s a big deal in my book!

The caching even understands that some URL’s are needlessly different on every request (social buttons, analytics etc.) so you can configure it to normalize those requests to a single recording that is played back every time. Your tests don’t really rely on gAnalytics working right?

And the best thing is, you don’t even have to change your tests.

You add something like this in your spec_helper.rb:

Billy.configuredo|c|
c.cache = true
c.ignore_params = ["http://www.google-analytics.com/__utm.gif",
"http://b.siftscience.com/i.gif",
"https://r.twimg.com/jot",
"http://p.twitter.com/t.gif",
"http://p.twitter.com/f.gif",
"http://www.facebook.com/plugins/like.php",
"https://www.facebook.com/dialog/oauth",
"http://cdn.api.twitter.com/1/urls/count.json"]
c.persist_cache = true
c.cache_path = 'spec/req_cache/'end# need to call this because of a race condition between persist_cache# being set and the proxy being loaded for the first time
Billy.proxy.restore_cache
Capybara.javascript_driver = :poltergeist_billy

Billy.configure do |c|
c.cache = true
c.ignore_params = ["http://www.google-analytics.com/__utm.gif",
"http://b.siftscience.com/i.gif",
"https://r.twimg.com/jot",
"http://p.twitter.com/t.gif",
"http://p.twitter.com/f.gif",
"http://www.facebook.com/plugins/like.php",
"https://www.facebook.com/dialog/oauth",
"http://cdn.api.twitter.com/1/urls/count.json"]
c.persist_cache = true
c.cache_path = 'spec/req_cache/'
end
# need to call this because of a race condition between persist_cache
# being set and the proxy being loaded for the first time
Billy.proxy.restore_cache
Capybara.javascript_driver = :poltergeist_billy

Related articles

Related

Learned something new? Want to become a better engineer? 💌

Join 9,400+ people just like you already improving their skills.

Here's how it works 👇

Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet 📖 right away. After that you'll get a thoughtfully written email every week about React, JavaScript, and lessons learned in my 20 years of writing code for companies ranging from tiny startups to Fortune5 behemoths.

Your Email Address 👇

Man, I love your way of writing these newsletters. Often very relatable and funny perspectives about the mundane struggles of a dev. Lightens up my day.
~ Kostas

PS: You should also follow me on twitter 👉 here. It's where I go to shoot the shit about programming.