Details
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
@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).
Activity
Field | Original Value | New Value |
---|---|---|
Issue Type | Improvement [ 4 ] | New Feature [ 2 ] |
Fix Version/s | 3.0 [ 16302 ] |
Fix Version/s | 3.1 [ 16511 ] | |
Fix Version/s | 3.0 [ 16302 ] |
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 ] |
Status | Open [ 1 ] | Resolved [ 5 ] |
Resolution | Fixed [ 1 ] |
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.