views:

79

answers:

2

Is it better to specify all the parameters of a given in one line, or each parameter on a seperate line? i.e. which is better?

seperate And for each parameter

Scenario: some random scenario
 Given a menu with a menu width of 19 
 And quit text of "quit" 
 And Fruit options of 
  |Text|
     |some text|
     When ...
     Then ...

or all the paremters for the specific Given on one line

Scenario: Some scenario
 Given a menu with  quit text of "quit" and menu width of 19 and Fruit options of 
  |Text|
     |Some text|
    When ... 
 Then ...

This appears (and I hope I'm wrong) to have the following implications for how you write your bindings, as well as starts to influence how you write your class, which it shouldnt! i.e. first option (seperate AND for each parameter ) the binding is easier to write if your class has public properties that are set one by one after the object is created...

private Menu _menu;
[Given(@"a menu of fruit options")]
public void GivenAMenuOfFruitOptions(Table table)
{
    string[] fruitOptions = table.GetColumn("Fruit");
    _menu = new Menu(fruitOptions,null);
}

[Given(@"a menu width of (.*)")]
public void GivenAMenuWidthOf(string width)
{
    _menu.Width = int.Parse(width);
}

[Given(@"a Quite text of ""(.*)""")]
public void GivenAMenuWidthOf(string quitText)
{
    _menu.QuitText = quitText;
}

whereas option two ( all on one line) it's easier to have an object with a constructor that takes all the parameters as constructor arguments.

private Menu _menu;
[Given(@"a menu with  quit text of ""(.*)"" and menu width of (\d+) and Fruit options of ")]
public void GivenAMenuOfFruitOptions(string quitText, int width, Table table)
{
    string[] fruitOptions = table.GetColumn("Fruit");
    _menu = new Menu(fruitOptions,width, quitText);
}

I feel as if I'm missing something, because the implementation of specflow should not influence the code I write, and I'm worried that #1 above will encourage overly stateful objects. I'm a functional stateless addict.

Any pointers will be most helpful.

txs in advance,

cheers, Alan

A: 

I am writing BDD style tests and I am using the first method because...

  1. The setup methods (also for verification) might get reused in related tests.
  2. Any failing tests will highlight the exact method that fails, including setup.
  3. Eliminates duplication for related tests and thus will be easier to maintain.
aqwert
Don't u think this will encourage ppl 2 design objects as "give me a simple empty object", and then set properties with a whole bunch of setters, instead of taking all the parameters in the constructor, which would be a bit more dependancy injection friendly? i.e. it will be possible to call the method under test without actually setting certain "setters". Allowing all the properties to be set independantly could result in needlessly complicated state (and default values) management?
alleycat
previous question is rhetorical. In reality I think that the "given's" will probably represent far more sophisticated business situations and not simple objects and setters. txs for the feedback, cheers, Al
alleycat
update: according to the Gherkin documentation, putting all on one line is an antipattern, see here: (http://wiki.github.com/aslakhellesoy/cucumber/conjunction-steps-antipattern)
alleycat
A: 

Not answering the full question, but just this part:

I feel as if I'm missing something, because the implementation of specflow should not influence the code I write, and I'm worried that #1 above will encourage overly stateful objects. I'm a functional stateless addict.

I don't think that it is a problem that the formulation of the scenarios influence the binding code. That's why it is a binding (other frameworks call it "glue" that emphasizes this even more). You can have a well designed business or automation logic that you have to drive with the binding code.

Functional/stateless: There is no built-in chaining option for the step bindings (the binding method returns something that the next receives), but you can create a kind of step context class (using context injection: http://github.com/techtalk/SpecFlow/tree/master/Tests/FeatureTests/ContextInjection/) where you can achieve a similar design.

Gaspar Nagy
Hi Gaspar -> yup, this should be a seperate question. I will post a different example showing where it's showing up as a problem for me and post it as a proper question that can be answered, txs for the pointer. Al
alleycat