How to list all cucumber step definitions

If you’re using cucumber you probably have step definitions split across several files, and you’re probably using a tool that doesn’t do a good job of listing the available step definitions (one of the biggest downsides of using cucumber).

What follows is a script that will list them all. It’s fairly rudimentary in that for each step definition it just lists the regex, any regex modifiers and the step definition arguments. It does everything I need at the moment so I haven’t developed it any further. Do with it what you will.


root_test_folder = "../my_project/features/support"

Dir.glob(File.join(root_test_folder,'**/*.rb')).each do |support_file|
  File.new(support_file).read.each_line do |line|
    next unless line =~ /^\s*(?:Given|When|Then)\s+\//
    matches = /(?:Given|When|Then)\s*\/(.*)\/([imxo]*)\s*do\s*(?:$|\|(.*)\|)/.match(line).captures
    matches[0] = Regexp.new(matches[0])
    puts matches.inspect
  end
end

Set the root_test_folder variable to the relevant location, run the file, and your console will be filled with what amounts to a step definition dictionary!

Cucumber step definition for debugging

Building on a previous post about debugging cucumber tests with ruby-debug, here’s a simple cucumber step definition you can use in your cucumber scenario in order to debug it:

Then /^I debug$/ do
  breakpoint
  0
end

Use it as follows:

Feature: Debug a cucumber scenario
  As a test writer
  In order to make my life easier
  I want to be able to debug

  Scenario: Calling the debugger in the middle of a test
    Given some condition
    Then I debug #this will call the debugger
    And I do something subsequent to debugging

Debugging cucumber tests with ruby-debug

Testing with cucumber blows test/unit out of the water, apart from one small aspect… I can’t use the Netbeans’ GUI debugger. The Netbeans debugger has been a joy to use, but sadly I have to say goodbye. So I’m left with using the traditional ruby debugger. It uses the same approach as gdb – console based debugging. Tedious and painful. Here’s how to use it…

Preparing your cucumber project

1) Install the gem with:
gem install ruby-debug

2) In your env.rb file, add the following at the top of the file:

require 'rubygems'
require 'ruby-debug'

3) If you want to be able to see stack traces, follow the above 2 lines with:
Debugger.start
(It might be worth wrapping that in some sort of debug-mode check as it does slow things down a little.)

Now you’re ready to debug like it’s 1979!

Using ruby-debug

To get started with ruby-debug, you need to set a breakpoint. How? Like this:


def some_method
  my_obj.thing = 4
  breakpoint #look! a breakpoint!
end

Breakpoints are set by writing breakpoint. Weird, huh? But there is a gotcha – breakpoint can’t be the last line of a method, or the debugger will stop at the calling method. So, you need to do something like this:


def some_method
  my_obj.thing = 4
  breakpoint
  0
end

…which is rubbish.

Once your breakpoint is set and you run the test, you’ll eventually see a command prompt – in Netbeans it’ll be in the output window. It’s time to debug.

Here are some of the commands that are available – they cover 95% of what I usually need from a debugger.

To end the debugging session and return control to the app:
quit

To find out where you are:
where
Note, this will print out a stack trace only if you’ve added the Debugger.start as specified above. If you haven’t, where will only print out the line number and file name of where execution has reached.

To see where you are in context (current line with a few lines before and after):
list

To print out the value of an individual variable:
p my_var

To print out all local and instance variables in the current stack frame:
info variables

To go to the next step (equivalent of ‘step into’):
step

To step over the next line:
next

To let the app run to the next breakpoint:
continue

To restart the app:
restart

You can see that ruby-debug gives you pretty much everything you need. The commands listed above hardly scratch the surface of what it can do. If you want to know more, here’s a good reference: http://bashdb.sourceforge.net/ruby-debug.html

BTW, here’s a post on how to wrap the breakpoint call in a cucumber step definition.