Cliff's idea about using anonymous methods got me thinking about ways
in which using BehaveN could be simplified.
Right now, I feel like setting things up to run scenarios written in
text is too different from scenarios written in code. For example,
scenarios written in text need the [Given], etc, attributes and they
need regular expressions to figure out the arguments.
I think the two approaches can be mostly homogenized.
I want to get rid of the attributes and regular expressions. I
realized that the patterns that Cliff and I worked out for
automatically formatting methods based on their names could be used to
match the methods, too.
For example, right now, you have to right this method to use from the
text syntax:
[When(@"adding (\d+) and (\d+)")]
public void adding_two_numbers(int a, int b)
{
_calculator.Add(a, b);
}
I want to change it to this:
public void When_adding_a_and_b(int a, int b)
{
_calculator,Add(a, b);
}
I can use reflection that uses the parameter types and names and the
method name to create the original regular expression.
Doing this brings the text syntax and the code syntax closer together.
No attributes, no regular expressions required in either case.
The other improvement I'd like to make is adding the steps to the
scenario in the code syntax.
Right now, we have to do this:
[Test]
public void AddingTwoNumbers()
{
Given(a_new_calculator);
When(adding_a_and_b, 1, 2);
Then(the_result_should_be, 3);
Verify();
}
Or using Cliff's suggestion:
[Test]
public void AddingTwoNumbers()
{
Add(Given_a_new_calculator);
Add(When_adding_a_and_b, 1, 2);
Add(Then_the_result_should_be, 3);
Verify();
}
What I'd really like is this:
public void AddingTwoNumbers()
{
Given_a_new_calculator();
When_adding_a_and_b(1, 2);
Then_the_result_should_be(3);
Verify();
}
There are a few advantages to this:
1. It looks more like the text syntax.
2. Any number of arguments are supported.
3. It looks more "natural" to me.
The only problem with this is that the the implementation of the
methods would have to change for it to work with the code syntax.
When_adding_a_and_b would have to look like this:
public void When_adding_a_and_b(int a, int b)
{
Execute(delegate { _calculator.Add(a, b); });
}
I need to "intercept" the actual code doing the work so that I can
infer the method name, catch any exception, filter the stack trace,
etc, so I continue executing the following steps.
It's a little ugly, but gets a tiny bit prettier if you're using .NET
3.5:
public void When_adding_a_and_b(int a, int b)
{
Execute(() => { _calculator.Add(a, b); });
}
OK, not that much prettier. Neither of these look natural to me.
The Execute method isn't necessary when using the text syntax, just
the code syntax. But it would work with both.
What do you think?
I have another idea using dynamic proxies, but it would require you to
put your scenario and step definitions in a separate class and marking
them as virtual. I'm not entirely sure if that would make it any
easier to use since you'd still have to write the test fixture that
invokes the methods in the other class. Of course, I could write my
own test runner (with a
TD.NET plug-in, of course) or an add-in for
NUnit, but I was trying to avoid that.
--
Jason