JBehave
  1. JBehave
  2. JBEHAVE-247

jBehave should be more intelligent/flexible with regards to prioritisation of steps

    Details

    • Type: New Feature New Feature
    • Status: Resolved Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 3.0
    • Component/s: Core
    • Labels:
      None
    • Patch Submitted:
      Yes
    • Number of attachments :
      2

      Description

      BDD's strength relies on being able to write fluent scenarios. jBehave's support for this is very good, but there is still room for improvement. For example a typical scenario might read...

      Scenario: Schedule Patient Discharge

      Given a medical patient called Bob Holness who is not medically fit
      When I change Bob's state to medically fit
      And select a discharge time of tomorrow morning
      And select a discharge complexity of 3
      Then Bob's discharge schedule should be displayed on the ward board

      Now in a related scenario let's say I want to cancel while rescheduling a discharge...

      Scenario: Cancel Rescheduling Patient Discharge

      Given a medical patient called Bob Holness who already has a discharge schedule
      When I reiterate that Bob's state is medically fit
      And select a discharge time of tomorrow morning
      And cancel the discharge schedule
      Then Bob's old discharge schedule should be displayed on the ward board

      The underlying implementation of assserting Bob's actual discharge schedule is the same, but I want to emphasise the expression of intent through use of words such as old, new, still, etc.

      jBehave partially supports this through aliases

      MySteps.java
      @Then('''$patient discharge schedule should be displayed on the ward board''')
      @Aliases(values=['''$patient old discharge schedule should be displayed on the ward board'''])
      public void assertDischargeScheduleOnWardPage(Patient patient) {
      	wardBoardPage.assertDischargeSchedule(patient)
      }
      

      The trouble is that the above fails because of the way in which jBehave matches and prioritises steps. Both "Then" and "Alias" steps will match the sentence
      "Bob's old discharge schedule should be displayed on the ward board", but "Then" will be prioritised based on it's declaration order, causing the value "Bob's old" to be passed to the PatientParameterConverter. Since no patient exists with the name "Bob's old", the parameter converter will return null and the test fails.

      Currently the workaround is to reword the steps slightly to prevent both of them matching...

      Then "Bob's" discharge schedule should be displayed on the ward board
      Then "Bob's" old discharge schedule should be displayed on the ward board

      or

      Then Bob's discharge schedule should be displayed on the ward board
      Then Bob's old discharge schedule should now be displayed on the ward board

      but both are inferior to the original. A nicer (and fairly easy) solution would be to base this priortisation on similarity with the string step, using something like the Levenshtein distance. Harder, but better yet would be to make the prioritsation configurable.

      I've attached the first solution (with lots of printlns so you can see how well the prioriisation works).

      1. LevenshteinDistance.java
        1 kB
        Stephen Cresswell
      2. PrioritizableUnmatchedToPendingStepCreator.java
        4 kB
        Stephen Cresswell

        Activity

        Hide
        Paul Hammant added a comment -

        Interesting. I've not looked at the patch. There is a prioritization scheme already (plain numeric attached to the annotation), but that's not why I'm commenting.

        Thinking about the language of what you're doing, and concentrating on the Given lines only :-

        Given a medical patient called Bob Holness who is not medically fit
        vs
        Given a medical patient called Bob Holness who already has a discharge schedule

        What it "who" were a synonym for And here?
        Such that, in terms of fitting the current JBehave, the Givens could be re-written as

        Given a medical patient called Bob Holness
        And is not medically fit
        vs
        Given a medical patient called Bob Holness
        And already has a discharge schedule

        Obviously that's more Inglish than English, but it could point to an enhancement where subtle 'And' breaks could be recognized at subjective or objective case pronouns*. Subject to configuration of course.

        Of course, your issue is with the matching of the Then line, not the Given. Towards that, have you thought about :-

        @Then("Then $Bob's $OldOrNot discharge schedule should be displayed on the ward board")

        Arghh... those two vars are too close together, and I'm not sure we can get an apostrophe-s situation to be left out of the matching group. Ok, ignore me.

        • Paul
        Show
        Paul Hammant added a comment - Interesting. I've not looked at the patch. There is a prioritization scheme already (plain numeric attached to the annotation), but that's not why I'm commenting. Thinking about the language of what you're doing, and concentrating on the Given lines only :- Given a medical patient called Bob Holness who is not medically fit vs Given a medical patient called Bob Holness who already has a discharge schedule What it "who" were a synonym for And here? Such that, in terms of fitting the current JBehave, the Givens could be re-written as Given a medical patient called Bob Holness And is not medically fit vs Given a medical patient called Bob Holness And already has a discharge schedule Obviously that's more Inglish than English, but it could point to an enhancement where subtle 'And' breaks could be recognized at subjective or objective case pronouns*. Subject to configuration of course. http://owl.english.purdue.edu/owl/resource/595/02/ Of course, your issue is with the matching of the Then line, not the Given. Towards that, have you thought about :- @Then("Then $Bob's $OldOrNot discharge schedule should be displayed on the ward board") Arghh... those two vars are too close together, and I'm not sure we can get an apostrophe-s situation to be left out of the matching group. Ok, ignore me. Paul
        Hide
        Stephen Cresswell added a comment -

        Hi Paul,

        Using Who and And interchangeably on a per step cases would work well. The Given steps I used as examples are some of our more simplistic, there are lots more variations...

        "a $gender, $speciality patient called $name, in "$location" who is $state
        e.g. Given a male, cardiovascular patient called Bob Holness, in "Bed 05, Ward 1", who is not medically fit

        Being able to split these up into smaller steps would make the scenarios more readable and reduce the number of complex steps....

        Given a male patient called Bob Holness // we should probably auto assign gender based on known names
        with a cardiovascular speciality
        located in Bed 05, Ward 1
        who is not medically fit

        "but" would be a useful synonym too

        Then Bob's bed changes to Bed 6
        but his* admission date stays as 15/07/74

        *our PatientParameterConverter is smart enough to recognise "his/her" and use the "current" patient from our test context instead of doing a db retrieval on first name

        Show
        Stephen Cresswell added a comment - Hi Paul, Using Who and And interchangeably on a per step cases would work well. The Given steps I used as examples are some of our more simplistic, there are lots more variations... "a $gender, $speciality patient called $name, in "$location" who is $state e.g. Given a male, cardiovascular patient called Bob Holness, in "Bed 05, Ward 1", who is not medically fit Being able to split these up into smaller steps would make the scenarios more readable and reduce the number of complex steps.... Given a male patient called Bob Holness // we should probably auto assign gender based on known names with a cardiovascular speciality located in Bed 05, Ward 1 who is not medically fit "but" would be a useful synonym too Then Bob's bed changes to Bed 6 but his* admission date stays as 15/07/74 *our PatientParameterConverter is smart enough to recognise "his/her" and use the "current" patient from our test context instead of doing a db retrieval on first name
        Mauro Talevi made changes -
        Field Original Value New Value
        Issue Type Improvement [ 4 ] New Feature [ 2 ]
        Fix Version/s 3.0 [ 16302 ]
        Mauro Talevi made changes -
        Fix Version/s 3.1 [ 16511 ]
        Fix Version/s 3.0 [ 16302 ]
        Mauro Talevi made changes -
        Summary jBehave should be more intelligent/flexible with regards to priortisation of steps jBehave should be more intelligent/flexible with regards to prioritisation of steps
        Fix Version/s 3.0 [ 16302 ]
        Fix Version/s 3.1 [ 16511 ]
        Component/s Core [ 11086 ]
        Hide
        Mauro Talevi added a comment -

        Added injectable PrioritisingStrategy in StepFinder with default ByPriorityField impl.
        Added alternative ByLevenshteinDistance impl.

        Show
        Mauro Talevi added a comment - Added injectable PrioritisingStrategy in StepFinder with default ByPriorityField impl. Added alternative ByLevenshteinDistance impl.
        Mauro Talevi made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]

          People

          • Assignee:
            Unassigned
            Reporter:
            Stephen Cresswell
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: