ngourd again

0 views
Skip to first unread message

liam

unread,
Nov 13, 2009, 2:34:29 AM11/13/09
to ozaltdotnet

I was watching Dr Nic's presentation, Dead simple JavaScript Unit
Testing in Rails, which is very good and relevant to anyone who writes
javascript.

http://drnicwilliams.com/2009/11/12/dead-simple-javascript-unit-testing-in-rails/

It got me thinking about the cucumber development rythm (http://
cukes.info):

1. Describe behaviour in plain text

2. Write a step definition

3. Run and watch it fail

4. Write code to make the step pass

5. Run and watch it pass

6. Repeat 2-5 until green like a cuke

7. Repeat 1-6 until the money runs out


So I have setup NGourd in a project so I can get some of this BDD
goodness. An NGourd step definition looks something like:

[Step(@"the page title should be (\w+)")]
public void should_have_title(string pageTitle)
{
NUnit.Framework.Assert.AreEqual(pageTitle, browser.Title);
}

It bothers me that every step definition tends to have duplication
between the text in the regular expression ("the page title should
be") and the method name. I'm thinking that the method name is
syntactic noise that exists because the method must have a name.

Is there a nice syntax that would allow steps to be defined as regular
expressions paired with anonymous methods?

Michael Minutillo

unread,
Nov 13, 2009, 2:45:10 AM11/13/09
to ozalt...@googlegroups.com
The short answer is "No" but I've been thinking about this as well. At the moment all of the step definitions are stored as delegates in a central repo and when the runner encounters a step it goes there, grabs the appropriate step container and runs the delegate on it. I think a more effective mechanism would be for the step container to register regexes for steps they can respond to and give them a generic ExecuteStep method (perhaps via an interface) then allow them to find and execute the correct code. This is more like the way MVC Controllers work. Then we could try all sorts of different registration techniques. Here's a couple of ideas I've been thinking about:

class MySteps
{
  public MySteps()
  {
    // EX: Go to www.ggogle.com
    Step("Go to (.+)", url =>
    {
      // .. Code
    });
  }

  // EX: When I Press Add
  public void Press_button(string button)
  {
    // ... code
  }
}

P.S. One of the things I actually like about the regex attribute way is that we can assign easily assign multiple sentence structures to the same action. i.e. Navigate To X and Go To X can both just be an Http Redirect
--
Michael M. Minutillo
Indiscriminate Information Sponge
Blog: http://wolfbyte-net.blogspot.com

Xerxes Battiwalla

unread,
Nov 13, 2009, 4:39:06 AM11/13/09
to ozalt...@googlegroups.com
My colleague and I have been having this exact discussion on and off for a few months. One idea we're kicking around is to remove the need for attributes altogether. Method names would use a convention to define the statement variables.

for example:
       public void should_have_page_title_0page_title0(string pageTitle)
 
The zero (0) is used as a delimiting character in absence of any other particularly distinguishable character thats allowable according to the language specification. The "page_title" definition in the name would be a fairly dumb string match. We've been using Cuke for a while now and haven't come across a situation where we needed the full power of a regular expression in order for a particular step - simple string substitution has worked just fine. Furthermore if you're using a pretty complex regex, it might mean that you should consider redefining your step differently (it might be doing too much).

On a related topic, has anyone here seen or used SpecFlow? Basically it's a full Cucumber parser and runner built in .NET. Some things are a bit naf, in particular the code-behind find it generates seems pretty ugly, but the way it integrates with VS & works with NUnit is cute. ATM they have their own Gherkin parser (with claimed 100% compatibility) but it looks like there are plans to integrate cuke's offical .NET Gherkin parser soon.

-xerx

Michael Minutillo

unread,
Nov 13, 2009, 4:47:58 AM11/13/09
to ozalt...@googlegroups.com
I'm not even sure that you would need the delimiters. If you have used reflection to get the name of the method you can just as easily get the name of the parameters as well. From there it's easy enough to build a simple regex using string substitution. Your example could be as simple as

public void should_have_page_title_pageTitle(string pageTitle) { ... }

Xerxes Battiwalla

unread,
Nov 13, 2009, 5:40:10 AM11/13/09
to ozalt...@googlegroups.com
Sure, thats certainly another alternative, though tying the argument name to the method name risks causing problems when you refactor the names.

One option i'm not comfortable with is having to define all my step definitions in a constructor as in your first example. It just feels dirty nesting that deep - reeks of trying to bend a language into directions it just wasnt intended to ;)

seeing as we're all on the same page so far, any other ideas?

-x

Liam McLennan

unread,
Nov 13, 2009, 5:38:38 PM11/13/09
to ozalt...@googlegroups.com
Michael's constructor-based example is reminiscent of fluent nhibernate. Does it bother you too?

I was thinking more along the lines of a collection:

public class NavigationSteps
{
    public Steps Navigation = new Steps
    {
        new Step(

            "Go to (.+)",
            url =>    
            {
                // .. Code
            }),
        new Step(
            "Enter (.+) and click (.+) button",
            (entry, buttonName) =>
            {
                // .. Code
            })
    }
}

In the above example it seems that the Step class would require a constructor overload for every overload of the Action<T> delegate. Is that right?
--
Liam McLennan.

li...@eclipsewebsolutions.com.au
http://www.eclipsewebsolutions.com.au

Xerxes Battiwalla

unread,
Nov 13, 2009, 6:41:56 PM11/13/09
to ozalt...@googlegroups.com
FNH and StructureMap's fluent config have one thing different to this - the flow makes logical sense from one construct to the next (thereby giving the fluency). Here, we're defining unique statement blocks completely unrelated to each other, the only reason they are in such close proximity and defined in a ctor is to work around the language - not because it makes fluent sense to do so.

your example with the List<Step> is better. Sure we still have to nest an extra level and fight the curly braces, but given that we're explicitly initializing the list of steps, the intention is clearer.

As for overloading Action<T> - yes, you would have to provide ctors for probably the first 3 (otherwise consider changing your feature), or downcast to Delegate and try doing some nifty reflection for arguments at the time of invocation 

-x

Liam McLennan

unread,
Nov 13, 2009, 7:30:39 PM11/13/09
to ozalt...@googlegroups.com
I no longer like the list based approach either. Compared to the current syntax I have replaced a meaningless method name with a lot of extra C# constructor / collection initialization noise. I prefer it how it is. At least it is simple.
Reply all
Reply to author
Forward
0 new messages