Skip to content

Instantly share code, notes, and snippets.

@manlycode
Created March 17, 2014 14:54
Show Gist options
  • Save manlycode/9600769 to your computer and use it in GitHub Desktop.
Save manlycode/9600769 to your computer and use it in GitHub Desktop.

Rails Testing Anti-patterns: Domino
I enjoy integration testing Rails applications. Not only because it’s anessential practice, but because I’m too lazy to have to click through anapplication on my browser if I don’t have to. I enjoy clean integration testseven more. My job is very easy when I can jump onto a new project and clearlyunderstand what an integration test is trying to prove.

Recently, I was shown a tool to improve the clarity of tests. The"Domino":https://github.com/ngauthier/domino Rubygem. Domino lets you seperateDOM selectors from your Capybara integration tests, and makes DOM assertionslook like a clean DSL than selector string scattered throughout your tests.

Being a fan of DLS and abstraction, I went bananas writing DSLs with Domino. Butquickly found out that made more work for myself. The following catalogs a fewof these pitfalls, and offer simpler alternatives.

Starting With Good Intentions

Starting out writing Domino classes, I understood the basics: a domelement has a selector, and an instance of the class has a node helper methodwhich returns a Capybara::Node object. So here’s an example of the code I waswriting:

In this example, I’m trying to assert the state of a shopping cart link. The cart will have an item count.

My thinking in writing this Domino class went something like this

Since I’m dealing with numbers, building the assertion so that I can use aRuby integer would be nice. That’s what I’d do if I were asserting the count onand ActiveRecord model, so I’ll make it look similar.

While this works, and provides a clean interface for RSpec assertions, Ieventually ran into some pitfalls.

Hitting a Brick wall

The DSL was great! The assertions green on full page loads, and I had a simpleway to communicate with clarity, what the test is checking.
But things were red once I introduced AJAX. Adding a cart item should increasethe count by 1:

Come on!

The JavaScript was correct. The mechanics of the client-side code worked when Iwould hand test it. What was going on?

Chucking breakpoints into the code revealed that the test was green when waitingbefore the assertion. It was a timing issue, the bane of exercising anyJavaScript heavy code.

Simplification with Domino Attributes

A shallow dive into Capybara’s documentation reminded me of how to wait for DOMupdates. You don’t. It automatically happens as long as you use Capybaramatchers (e.g. have_content, have_css). So I refactored:

This example leverages a Domino attribute". Attributes specify a helper method on theclass which returns a DOM element within the selector, having the “.count” class.

This impacts the overall assertion used in the test. It doesn’t use an integerto compare anymore, instead a string. The trade-off is a few extra characters inthe test, but the have_content matcher is less brittle than eql matcher. Additionally, it waits for the DOM to update. So we trade off a few characters for better, green tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment