Terrible Blog

Because Terrible Labs loves you.

Introducing Motion-juxtapose

| Comments

We’re big on RubyMotion at Terrible Labs. Over the last year since we’ve adopted it, we’ve found it to be a fantastic way to write iOS apps in a language we love without compromising on a native experience. Along the way, we’ve developed some nifty tricks we’d like to share with the rest of the world.

Today, I want to introduce motion-juxtapose, a library for adding screenshot-driven assertions to your RubyMotion tests.

What does this do?

Literally, it_should_look_like "the login screen" in your specs.

  1. Write a test that puts your app in the state you want to capture and make a screenshot assertion.

    A simple controller test might look like:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    describe "HomeController" do
    
      before do
        controller.languages = [:english, :spanish, :mandarin]
      end
    
      tests HomeController
    
      it "shows hello world in many languages after login" do
        it_should_look_like "home screen with three greetings"
      end
    end
    
  2. The first time this assertion is made, your test will fail with the error “No accepted screen shot”.

  3. Run the juxtapose server with `bundle exec juxtapose` and browse to http://localhost:4567 — you should see the just-captured screenshot, like below.

  4. If the screenshot looks like what you expect, click Accept to save the image. Future runs of this test will be compared against the accepted one.

  5. Run the tests again, and they should be green.

  6. Later, when you introduce a change (intentionally or not), the tests will fail with the message “Screenshot did not match”. Open up the juxtapose server again, and you’ll see a comparison of your accepted screenshot with what the test captured.

  7. If the change was intentional, you can accept the new screenshot - otherwise, you’ve got some fixin’ to do!

Where do we use this?

We use screenshot assertions to supplement our isolated model and controller tests, not to replace them. Since they don’t inform the design of the code they’re testing, screenshot assertions don’t help you write better code, nor can they be used for TDD. Instead, they’re designed to help write tests that guard against visual and functional regressions.

We use motion-juxtapose in two main ways:

  • In controller tests, for checking the visual appearance of a controller under a variety of states and edge cases. (When your signup controller has Save tapped with an empty password field, is the field highlighted the right way?)
  • In integration tests (using motion-frank), for verifying that the app looks the way we expect as we run through scenarios as a user. (After I sign up, fill in my zip code, and post a status update does it show up on my home screen?)

It’s also been useful when we’ve inherited an app with no tests. Screenshot assertions are a quick way to wrap an existing project in a set of black-box tests that capture a bunch of information about an application’s behavior. This lets us begin refactoring without as much fear of regressions.

We’d love to hear what you think

Head over to GitHub for the rest of the story and try out motion-juxtapose on your next project!

Comments