A First Attempt
active variable. Our first attempt at fixing our test teardown problem was adding an after block for each feature test that waited for all active AJAX requests to complete:
Bringing Out The Big Guns
The basic outline of our more complete solution was to do the following during test teardown:
- Prevent the server from accepting any new requests
- Prevent the client from making any new requests
- Wait until all active requests complete
To implement this solution we first wrote a piece of Rack middleware that would take care of #1 and #3 (for an introduction to Rack middleware checkout this RailsCast):
The next hurdle was to figure out how to prevent the client from making any new AJAX requests. We contemplated adding a JQuery
ajaxSend() handler to block any new AJAX request but instead settled on a simpler solution of just navigating to the about:blank page. This would prevent the client from making any new AJAX requests as well as requesting any other resources. With all these changes here's what our spec_helper looked liked:
We updated our test environment to insert our
RackRequestBlocker at the beginning of the Rack middleware chain:
Finally we had to add our dependency on the atomic gem to our Gemfile:
That's it! Goodbye deadlocks and timeouts! Hello clean test runs!
I'm happy to report that our tests have been deadlock and timeout free since making these changes to our test infrastructure. Have you faced similar problems writing reliable feature tests? If so, drop us a comment. We'd love to hear about it.