Using Capybara to test JavaScript that makes HTTP requests

1,661 views
Skip to first unread message

Dan Croak

unread,
Nov 1, 2012, 3:45:38 PM11/1/12
to boston-r...@googlegroups.com
Hey folks,

With more and more of our Rails apps being tested with a Capybara driver that can execute Javascript (such as Capybara Webkit), while also using more JavaScript libraries like Stripe.js or Facebook's JavaScript client, we've noticed more acceptance test suites making HTTP requests from the Javascript code.

That's a problem the Ruby community has solved pretty well with tools like WebMock, VCR, and others stubbing out Net::HTTP.

It took me awhile to wrap my head around the components involved in doing something similar for Capybara Webkit suites until Joe wrote up this post:

http://robots.thoughtbot.com/post/34761570235/using-capybara-to-test-javascript-that-makes-http

Would love to get your feedback on the technique.

Cheers,
Dan

Andrew DiMichele

unread,
Nov 1, 2012, 4:49:22 PM11/1/12
to boston-r...@googlegroups.com
Hey Dan,

Have you guys tried using Jasmine (http://pivotal.github.com/jasmine/) for your client-side JS testing?

We were originally using Capybara-Webkit for our client-side testing and have recently started migrating over to Jasmine for the JS-centric tests. It feels a lot like rspec and supports mocks, html fixtures, and even stubbing ajax requests. The tests themselves are extremely fast and don't suffer from certain race conditions like Capybara-Webkit does.

Nice writeup though... I thought your solution was very clever!

- Andrew

--
 
 

Dan Croak

unread,
Nov 1, 2012, 5:10:05 PM11/1/12
to boston-r...@googlegroups.com
Hey Andrew,

We have used Jasmine although I don't personally have much experience with it.

I didn't know about the stubbing Ajax responses. That sounds pretty cool. Do you use https://github.com/pivotal/jasmine-ajax for that? Do you have example code you can share that shows what those tests look like?

Dan


--
 
 

Patrick Robertson

unread,
Nov 1, 2012, 5:16:52 PM11/1/12
to boston-r...@googlegroups.com
I generally also find capybara to be less than ideal for doing testing in JS.  I use the sinon library (http://sinonjs.org/) for ajax request stubbing.  It helps preserve the four phase test pattern more strongly than the jasmine stubbing library.  

I tend to avoid using the ajax stubs when writing backbone.js code though.  Sinon stubs are capable of yielding to a callback and that places very nicely with Backbone.Collection#fetch and Backbone.Model#fetch.  Here's a gist I wrote for Mark Bates a while ago demonstrating the functionality:

- Patrick
--
 
 

Brian Cardarella

unread,
Nov 1, 2012, 5:28:21 PM11/1/12
to Boston Ruby Group
We've been using Poltergeist for doing our integration testing. Works well for the most part, every so often we'll have to play around with putting sleeps around our test suite so async stuff works.


----------------------
Brian Cardarella
Principal at DockYard
Visit us: http://dockyard.com
Call us: (855) DOCK-YRD
Follow me on Twitter: http://twitter.com/bcardarella
Follow us on Twitter: http://twitter.com/DockYard


--
 
 

Dan Croak

unread,
Nov 1, 2012, 5:28:35 PM11/1/12
to boston-r...@googlegroups.com
Sinon looks really nice. Have you used that fakeServer bit?

Are you using these tools for acceptance tests? The above example looks more like a unit test to me.



--
 
 

Dan Croak

unread,
Nov 1, 2012, 5:36:55 PM11/1/12
to boston-r...@googlegroups.com
Brian,

Cool. What are you doing for the external HTTP request bit within Poltergeist? Do your Poltergeist tests hit things like Stripe, do you stub out those calls, set up a fake like in the blog post, or something else?

Dan


--
 
 

Brian Cardarella

unread,
Nov 1, 2012, 5:42:05 PM11/1/12
to Boston Ruby Group
Dan McClain took a look at your post today, this is definitely something that we will try to integrate in to our workflow. Currently we are doing actually HTTP requests to outside resources such as Stripe's sandbox. It's pretty slow and not ideal. Thank you guys for coming up with a solution.


----------------------
Brian Cardarella
Principal at DockYard
Visit us: http://dockyard.com
Call us: (855) DOCK-YRD
Follow me on Twitter: http://twitter.com/bcardarella
Follow us on Twitter: http://twitter.com/DockYard


--
 
 

Dylan Griffin

unread,
Nov 1, 2012, 6:18:59 PM11/1/12
to boston-r...@googlegroups.com
Dan,

I was just using Sinon's fakeServer today, this is what it looks like: https://gist.github.com/3997036

Pretty cool stuff, and using a helper, I can keep the JSON response I want in a different file.

-Dylan
--
 
 

Phil Darnowsky

unread,
Nov 1, 2012, 6:54:59 PM11/1/12
to boston-r...@googlegroups.com
Coincidentally we just started doing the same thing here: Poltergeist plus real HTTP calls, but attempting to move towards mocking those out.
--
 
 

Andrew DiMichele

unread,
Nov 2, 2012, 12:41:47 PM11/2/12
to boston-r...@googlegroups.com
Dan - yes, we are using jasmine-ajax. Here's a snippet from our test suite: https://gist.github.com/7608f32ccb46f38eab04

The json fixture you see there is generated from our controller specs... we wrote some code to spit those out trivially.

I actually wasn't familiar with sinonjs, and the FakeXMLHttpRequest api looks very cool! I'll have to give it a try.

- Andrew


--
 
 

Reply all
Reply to author
Forward
0 new messages