JBehave
  1. JBehave
  2. JBEHAVE-232

Replace @Named variable annotation by pattern matching of variable names used in step annotation

    Details

    • Type: Improvement Improvement
    • Status: Open Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.3.2
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
      None
    • Number of attachments :
      0

      Description

      If the @Named annotation was deprecated, and the $variable patterns were matched to the steps argument list instead, jBehave would be much more usable.

      The @Named parameter annotations are in essence redundant, and they limit usability of jBehave for two reasons:

      1. The parameter names could be parsed directly from the step scenario instead. And I wish they were: I (and my testers) have frequently run into the problem of the arguments being in the wrong order. An innocent looking step like

      @Given("a book $book written by $author")
      @Alias("$author's book $book")
      public void setBookAndAuthor(@Named("author") String author, @Named("book") String book) {...}
      

      can lead to great confusion, with the arguments getting switched. Using the step in an example scenario can increase the confusion, as one can legally write:

      Given a book [author] written by [book]
      

      Testers and developers alike are also confused that, while Given a book Moby Dick written by Herman Melville works, Given [title] written by [person] doesn't (see next point).

      2. they inhibit reusing steps in example scenarios; either that, or they lead to redundant columns.
      An example to illustrate this: given

      @Given("a stock named $stock")
      public void createStock(@Named("stock") String stock)...
      

      I cannot reuse this step for two colums in an example:

         Scenario: client creates two stocks
         Given a stock named [A]
         And a stock named [B]
         
         Examples:
         |A          |B         |
         |GOOG | AAPL |
      

        Activity

        Hide
        Paul Hammant added a comment -

        I don't understand. I've been deeply involved in the @Named work and the Paranamer integration (which negates the need for @Named for those who're comfy with the informality it introduces), and don't follow what the issue is. Can we have an attached testcase that fails when it should work ? Thanks.

        Show
        Paul Hammant added a comment - I don't understand. I've been deeply involved in the @Named work and the Paranamer integration (which negates the need for @Named for those who're comfy with the informality it introduces), and don't follow what the issue is. Can we have an attached testcase that fails when it should work ? Thanks.
        Hide
        Jonathan Ross added a comment -

        Hi Paul. Sorry if my examples weren't clear enough. I was not familiar with the Paranamer functionality when I entered this issue, indeed it seems that this addresses my first point quite nicely.

        Regarding my second point, what I would like to be able to do, is to use a single step multiple times in an example table. Take the following scenario (using the steps from the trader scenarios from org.jbehave.examples):

        Scenario: Example table trying to reuse the step with another column
        Given a stock of <first symbol> and a <first threshold>
        And a stock of <second symbol> and a <second threshold>
        
        Examples:
        |first symbol|first threshold|second symbol|second threshold|
        |B           |10             |B            |20              |
        

        Running this scenario using a recent trunk revision of jBehave (revision 1661) leads to

        Given a stock of <first symbol> and a <first threshold> (PENDING)
        And a stock of <second symbol> and a <second threshold> (PENDING)
        

        I think it should be possible to name the parameter anything in the scenario file, regardless of the exact parameter names declared in the step annotation. Currently the only way I can come up with that would work is to explicitly chain steps with all the parameter names used in the scenario, like this:

            @Given("a stock of symbol %symbol and a threshold of %threshold")
            @Alias("a stock of <symbol> and a <threshold>") // alias used with examples table
            public void aStock(@Named("symbol") String symbol, @Named("threshold") double threshold) {
                stock = service.newStock(symbol, threshold);
            }
        
            @Given("a stock of <first symbol> and a <first threshold>")
            public void aFirstStock(@Named("first symbol") String symbol, @Named("first threshold") double threshold) {
                aStock(symbol, threshold);
            }
            
            @Given("a stock of <second symbol> and a <second threshold>")
            public void aSedondStock(@Named("second symbol") String symbol, @Named("second threshold") double threshold) {
                aStock(symbol, threshold);
            }
        

        To be honest, I think that it is strange to have to introduce separate aliases for tables at all. I would like to be able to run the example scenario above with one single @Given annotation:

            @Given("a stock of $symbol and a $threshold") // alias used with examples table
            public void aStock(String symbol, double threshold) {
                stock = service.newStock(symbol, threshold);
            }
        
        Show
        Jonathan Ross added a comment - Hi Paul. Sorry if my examples weren't clear enough. I was not familiar with the Paranamer functionality when I entered this issue, indeed it seems that this addresses my first point quite nicely. Regarding my second point, what I would like to be able to do, is to use a single step multiple times in an example table. Take the following scenario (using the steps from the trader scenarios from org.jbehave.examples): Scenario: Example table trying to reuse the step with another column Given a stock of <first symbol> and a <first threshold> And a stock of <second symbol> and a <second threshold> Examples: |first symbol|first threshold|second symbol|second threshold| |B |10 |B |20 | Running this scenario using a recent trunk revision of jBehave (revision 1661) leads to Given a stock of <first symbol> and a <first threshold> (PENDING) And a stock of <second symbol> and a <second threshold> (PENDING) I think it should be possible to name the parameter anything in the scenario file, regardless of the exact parameter names declared in the step annotation. Currently the only way I can come up with that would work is to explicitly chain steps with all the parameter names used in the scenario, like this: @Given("a stock of symbol %symbol and a threshold of %threshold") @Alias("a stock of <symbol> and a <threshold>") // alias used with examples table public void aStock(@Named("symbol") String symbol, @Named("threshold") double threshold) { stock = service.newStock(symbol, threshold); } @Given("a stock of <first symbol> and a <first threshold>") public void aFirstStock(@Named("first symbol") String symbol, @Named("first threshold") double threshold) { aStock(symbol, threshold); } @Given("a stock of <second symbol> and a <second threshold>") public void aSedondStock(@Named("second symbol") String symbol, @Named("second threshold") double threshold) { aStock(symbol, threshold); } To be honest, I think that it is strange to have to introduce separate aliases for tables at all. I would like to be able to run the example scenario above with one single @Given annotation: @Given("a stock of $symbol and a $threshold") // alias used with examples table public void aStock(String symbol, double threshold) { stock = service.newStock(symbol, threshold); }
        Hide
        Richard Larson added a comment -

        I definitely would appreciate having this issue be resolved, we are currently thinking of switching from jbehave to another BDD framework due to the inability to reuse our steps.

        Show
        Richard Larson added a comment - I definitely would appreciate having this issue be resolved, we are currently thinking of switching from jbehave to another BDD framework due to the inability to reuse our steps.
        Hide
        Olmo Rigolo added a comment - - edited

        Hi all,

        this http://jira.codehaus.org/browse/JBEHAVE-748 Bug can be used as a workaround for your problem. Here is a example implementation:

        Scenario: Combination of variable and example-data
        When user sets 'usernameField' to <value>
        When user sets 'passwordField' to <value>
        
        Examples:
        value
        username
        password
        
        @When("user sets '$fieldname' to <value>")
        public void whenUserSetsUsernameFieldTovalue(@Named("fieldname") final String fieldname, @Named("value") final String value) { 
           System.out.println(fieldname + value); 
        }
        

        Does this fix your problem?

        edit: I would prefer to not use a bug as a workaround, so I vote for this issue to be fixed.

        Show
        Olmo Rigolo added a comment - - edited Hi all, this http://jira.codehaus.org/browse/JBEHAVE-748 Bug can be used as a workaround for your problem. Here is a example implementation: Scenario: Combination of variable and example-data When user sets 'usernameField' to <value> When user sets 'passwordField' to <value> Examples: value username password @When( "user sets '$fieldname' to <value>" ) public void whenUserSetsUsernameFieldTovalue(@Named( "fieldname" ) final String fieldname, @Named( "value" ) final String value) { System .out.println(fieldname + value); } Does this fix your problem? edit: I would prefer to not use a bug as a workaround, so I vote for this issue to be fixed.

          People

          • Assignee:
            Unassigned
            Reporter:
            Jonathan Ross
          • Votes:
            2 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: