Skip to main content

Magic: strings and regular expressions in ruby Cucumber tables


I stumbled on an interesting trick that is worth documenting

Say you have a Cucumber Scenario Outline like so:

 Scenario Outline: Foo and bar
    When I click < foo >
    Then < bar > should appear in the page
  Examples:
    | foo        | bar                |
    | X          | =String or regex   |
    | Y          | ===String or regex |
    | Z          |  String or regex   |

and we use it like so:

Then(/^(.+) should appear in the page$/) do |bar|
  on(FooPage).page_contents.should match Regexp.new(bar)
end 

but this won't work, because the case with "=" will pass by accident if page_contents erroneously contains "===" instead.  And case Z would always pass no matter how many '=' characters are in the page.  (That's clear, right?  Say something in the comments if that doesn't make sense to you.)

Also, I really need to check for a leading space for case Z, so what I think I need is not a string but a regular expression, so those anchor carets below should work, right?

  Examples:
    | foo        | bar                 |
    | X          | ^=String or regex   |
    | Y          | ^===String or regex |
    | Z          | ^ String or regex   |

That seems reasonable.  I've made sure that the values for 'bar' are interpreted as regexes, so this should Just Work...

What I discovered is that the values for 'bar' are actually magically turned into *escaped* regexes, so what ends up being compared to page_contents is actually:

/\^\=String or regex/
/\^\=\=\=String or regex/
/\^ String or regex/


and that is no help at all.  Even though they are regexes, the anchor characters are being escaped within the regex so the arguments continue to function as strings.  That is, what is being sent to RSpec as the argument to match is equivalent to the literal strings

"^=String or regex"
"^===String or regex"
"^ String or regex"

and of course that isn't what we want at all.

Here is what I finally figured out:

First we put the regexes that we want to use inside a pair of some character, in this case single quotes.  (And it works for leading spaces in strings, too!)

  Examples:
    | foo        | bar                   |
    | X          | '^=String or regex'   |
    | Y          | '^===String or regex' |
    | Z          | '^ String or regex'   |

Here's the tricky part.  Before we do the match in RSpec we strip the single quotes, and hey presto the result is an unescaped regex *not* a string:

Then(/^(.+) should appear in the page$/) do |bar|
  bar = bar.gsub(/'/, '')
  on(FooPage).page_contents.should match Regexp.new(bar)
end 

That is, what gets sent to RSpec as the argument to 'match' ends up being

/^=String or regex/
/^===String or regex/
/^ String or regex/

and is correctly interpreted by RSpec as a regex-- not as an escaped regex and not a string either.

Sometimes you can have a little too much magic.

Comments

Austin Ian said…
This comment has been removed by a blog administrator.
Win vinaya said…
This comment has been removed by a blog administrator.
Leslie Lim said…
This comment has been removed by a blog administrator.
lee woo said…
This comment has been removed by a blog administrator.

Popular posts from this blog

Reviewing "Context Driven Approach to Automation in Testing"

I recently had occasion to read the "Context Driven Approach to Automation in Testing". As a professional software tester with extensive experience in test automation at the user interface (both UI and API) for the last decade or more for organizations such as Thoughtworks, Wikipedia, Salesforce, and others, I found it a nostalgic mixture of FUD (Fear, Uncertainty, Doubt), propaganda, ignorance and obfuscation. 

It was weirdly nostalgic for me: take away the obfuscatory modern propaganda terminology and it could be an artifact directly out of the test automation landscape circa 1998 when vendors, in the absence of any competition, foisted broken tools like WinRunner and SilkTest on gullible customers, when Open Source was exotic, when the World Wide Web was novel. Times have changed since 1998, but the CDT approach to test automation has not changed with it. I'd like to point out the deficiencies in this document as a warning to people who might be tempted to take it se…

Watir is What You Use Instead When Local Conditions Make Automated Browser Testing Otherwise Difficult.

I spent last weekend in Toronto talking to Titus Fortner, Jeff "Cheezy" Morgan, Bret Pettichord, and a number of other experts involved with the Watir project. There are a few things you should know:

The primary audience and target user group for Watir is people who use programming languages other than Ruby, and also people who do little or no programming at all. Let's say that again:

The most important audience for Watir is not Ruby programmers 
Let's talk about "local conditions":

it may be that the language in which you work does not support Selenium
I have been involved with Watir since the very beginning, but I started using modern Watir with the Wikimedia Foundation to test Wikipedia software. The main language of Wikipedia is PHP, in which Selenium is not fully supported, and in which automated testing in general is difficult. Watir/Ruby was a great choice to do browser testing.  At the time we started the project, there were no selenium bindings for …

Open letter to the Association for Software Testing

To the Association for Software Testing:

Considering the discussion in the software testing community with regard to my blog post "Test is a Ghetto", I ask the Board of the AST  to release a statement regarding the relationship of the AST with Keith Klain and Per Scholas, particularly in regard to the lawsuit for fraud filed by Doran Jones (PDF download link) .

The AST has a Code of Ethics  and I also ask the AST Board to release a public statement on whether the AST would consider creating an Ethics Committee similar to, or as a part of the recently created Committee on Standards and Professional Practices.

The yearly election for the Board of the AST happens in just a few weeks, and I hope that the candidates for the Board and the voting members of the Association for Software Testing will consider these requests with the gravity they deserve.