Running individual specs with RubyMotion

I’m testing parts of Shortcat (which as of v0.4.0 is in Objective-C) with RubyMotion, which is pretty nifty since I’m much more comfortable in Ruby than Objective-C and writing tests is way easier in Ruby. However, it’s far from the fully-featured RSpec like I’m used to.

When working on a class, I like to only run specs for that particular file to keep the runtimes down, then run all the specs later. In RubyMotion, you can achieve this with:

1
$ rake spec files=foo_spec,spec/bar_spec.rb

(via http://www.rubymotion.com/developer-center/articles/testing/#_run_selected_spec_files

However, I couldn’t see any obvious way to run individual specs, which is useful when trying to focus on a particular spec. So I dug into the spec.rb in /Library/RubyMotion/lib/motion/, which seems to be just a copy of MacBacon, and found this:

/Library/RubyMotion/lib/motion/bacon.rb
1
2
3
4
5
6
7
8
9
module Bacon
  ...

  RestrictName    = //  unless defined? RestrictName
  RestrictContext = //  unless defined? RestrictContext

  Backtraces = true  unless defined? Backtraces

  ...

After checking the it function around line 503 (it may be different on yours), the name of the spec is regex matched against RestrictName and if it matches, it runs the spec. Unfortunately, RestrictContext isn’t used yet but there’s a TODO for it there. I tried uncommenting the line, but it seems to just hang for me and given I don’t really care for it, I haven’t looked into it further.

I came up with a bit of code that lets you filter by spec name when running rake spec. I also added support for RestrictContext for when that gets implemented, as well as the ability to hide the backtrace. Place this in spec/helpers/spec_options.rb:

Usage:

1
2
3
4
$ rake spec filter="name of spec"                   # To filter by spec name
$ rake spec files=foo_spec filter="name of spec"
$ rake spec filter_context="this doesn't work yet"  # To filter by context name (doesn't work until MacBacon implements it)
$ rake spec hide_backtraces=yes                     # Hide backtraces

Hope this helps!

Comments