Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Simple Test Parallelization

Hunter Gillane
Monday, May 20, 2013

Let’s look at a simple approach to parallelizing a test suite for a Ruby app. Parallelizing your specs can be a good strategy to get a speedup on an existing slow suite. It can also be employed early on a greenfield project as part of a commitment to fast tests. The same caveats that Andrew mentions in that article post here as well, namely that parallelization might mask more important design changes you need to make in you suite.

While you could use a gem like parallel_tests, let’s look at what it would take to achieve this without needing to pull in another dependency.

The only requirement to employ this approach is that the parts of your build that you want to parallelize do not share a database, or if they do, that it will not cause test pollution if your specs run at the same time. These parallelizable portions of your build could be Rails engines, a library in lib, an unbuilt gem, or any other isolated piece of your app. If your app doesn’t meet that requirement, something like parallel_tests will likely be more useful.

Let’s assume that you are using engines to organize functionality in your app. In this case you likely are already using a separate database for each engine’s test suite, so let’s use that as a basis for our example. Assuming that you have two engines (engine1 and engine2) and they are both in the engines directory, you could write a rake task that parallelizes your build that looks something like this:


task :build do
  build_pids = []

  %w{engine1 engine2}.each do |engine_name|
    build_pids << fork { exec "cd engines/#{engine_name} && rspec spec" }
  end

  trap(:INT) do
    build_pids.each do |pid|
      begin
        Process.kill(:INT, pid)
      rescue Errno::ESRCH
      end
    end
  end

  Process.waitall.each do |pid, status|
    unless status.success?
      puts "Build failed"
      exit 1
    end
  end

  puts "Build successful"
  exit 0
end

This rake task does three things:

  • Uses fork+exec to kick off child processes to run each engine’s build
  • Collects the child processes after they have completed and exits non-zero if any of the child build processes were unsuccessful
  • Captures INT so that all child build processes will be killed when you Ctrl-C in the terminal

The output can be ugly but may be worth the time savings, especially if you only are going to be running this task as a last check before CI.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Boulder Standup – Feb 24, 2012

Hunter Gillane
Friday, February 24, 2012

Helps

  • RubyMine 4 is scrolling to the bottom of the window when displaying test results.

Click the gear in the test runner window and click “Select First Failed Test When Finished”

Interestings

  • grep_routes
    Tyler from Boulder office mate Everlater wrote a gem called grep_routes. It lets you search your routes without loading all of Rails. Only works with Rails 3.1 and 3.2.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Terminal: Beyond Ctrl + A and Ctrl + E

Hunter Gillane
Saturday, November 12, 2011

Update: I had some of the Ctrl and Option commands switched. Fixed now.

As Rails developers, we spend most of our day in two places: an IDE/text editor and the command line. While we spend much time learning shortcuts that help us write and refactor our source code more quickly, many of us are perfectly okay just learning Ctrl + A and Ctrl + E and holding down the arrow keys to place the cursor where we want to get to on the command line.

Don’t do that. With only a handful of additional commands, your day to day interaction with the terminal can be much more pleasant. Here are a few ways to do that using terminal and the bash shell.

A Command Line Editing Starter Pack

Here’s a quick list of commands that you’ll get a lot of day to day usage from, if you aren’t already:

  • Ctrl + A: Move cursor to the beginning of the line
  • Ctrl + E: Move cursor to the end of the line
  • Ctrl + K: Delete from cursor to the end of the line
  • Option + F: Move cursor one word forward
  • Option + B: Move cursor one word backward
  • Option + D: Delete next word
  • Option + Delete: Delete previous word

Note: You’ll need to set your meta key to Option before the commands that use Option will work (see below).

These seven simple commands will help you move more nimbly when editing text on the commands line. There is certainly plenty more you can do, which you can find in the bash manual.

A Word on Modes

By default, the bash shell run in emacs mode. This means that emacs shortcuts are enabled by default.

Emacs mode uses a Meta key for some commands, and the Option key is a good choice. In Terminal on OS X, you’ll need to enable this by going to Preferences > Settings > Keyboard and checking “Use option as meta key.”

You can also tell bash you want to use vi mode for command line editing with set -o vi, if for some reason you want to type i before every cd or ls you write.

End

Nothing new or overwhelmingly exciting here, and there is certainly much more to dive into if you are so inclined. However, this small set of commands will have you covered for the majority of your day to day command line editing needs and is what I would consider constitutes a minimum level of proficiency.

Give your arrow keys a break!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Hunter Gillane

Hunter Gillane
Boulder

Subscribe to Hunter's Feed

Author Topics

engines (1)
parallelism (1)
testing (1)
terminal (1)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >