godog icon indicating copy to clipboard operation
godog copied to clipboard

Replace the generic Step function with Given/When/Then functions to match the majority of other languages

Open mirogta opened this issue 1 year ago • 14 comments

🤔 What's the problem you're trying to solve?

I'm trying to add support for Go (godog) to Cucumber language service, so that we can finally use Go BDD support in VSCode.

It's a bit tricky because of the generic Step func and not having the separate Given/When/Then funcs instead.

Raised a poll here: https://github.com/cucumber/godog/discussions/542

✨ What's your proposed solution?

  • Mark the Step function as deprecated
  • Add 3 new functions to match their respective counterparts in the feature files - Given/When/Then

⛏ Have you considered any alternatives or workarounds?

No alternatives considered. I think we should "just" do this to keep the syntax consistent with other programming languages.

📚 Any additional context?


This text was originally generated from a template, then edited by hand. You can modify the template here.

mirogta avatar Mar 15 '23 15:03 mirogta

Hello @mirogta, One thing to note is we have already introduced Given/When/Then functions as part of: https://github.com/cucumber/godog/pull/509 The above is not released yet, but the functions will be available once released. The Step function is not deprecated at this point though.

otrava7 avatar Mar 15 '23 16:03 otrava7

Looking at https://github.com/cucumber/godog/blob/bcffb1c82995fce67615aa77db22c05bfe4757e7/test_context.go#L261, there are already funcs Given/When/Then. So we can perhaps mark the "preferred" Step func as obsolete.

Concern about terminology: The hooks BeforeStep and AfterStep should stay. Assuming these can be explained in the docs, as in Given/When/Then are the actual funcs and Step is just their abstraction.

mirogta avatar Mar 15 '23 17:03 mirogta

@otrava7 thanks - yeah, found it as well now.

I'm looking at this more holistically, i.e. can we also replace the generic Step everywhere else, in the snippets, in the documentation & examples etc.

mirogta avatar Mar 15 '23 17:03 mirogta

That makes sense to me!

otrava7 avatar Mar 15 '23 17:03 otrava7

On a related note, the docs say, at https://github.com/cucumber/godog:

Alternatively, you can also specify the keyword (Given, When, Then...) when creating the step definitions:

But that doesn't work when go.mod says require github.com/cucumber/godog v0.12.6 because you get this instead:

./godogs_test.go:18:6: ctx.Given undefined (type *godog.ScenarioContext has no field or method Given)

seanw2020 avatar Mar 21 '23 03:03 seanw2020

@seanw2020 Recent changes have not been released as a tagged version yet, however you can go ahead and upgrade to latest main by go get -u github.com/cucumber/godog@main.

vearutop avatar Mar 21 '23 11:03 vearutop

I'm keen to start working on this. Just checking that no one has started already

otrava7 avatar Apr 04 '23 12:04 otrava7

@otrava7 that's great! I've started looking into it to understand the scope and effort a bit more, but very happy for someone else to actually deliver it. Hope the (WIP) branch above helps.

mirogta avatar Apr 04 '23 13:04 mirogta

That's more or less what I was planning to do as well, is there anything else you were looking to do?

otrava7 avatar Apr 04 '23 14:04 otrava7

That's more or less what I was planning to do as well, is there anything else you were looking to do?

No, that's it.

Observations:

  • There are tests for the Step definition having different meaning: Given/When/Then. Does it actually make sense? That made it a bit difficult to choose which keyword should the Step be replaced with, but I've made the best guesses. Should it even be allowed? E.g. if I have an assert (Then) then how would it make sense to use it in arrangement (Given)?
  • There's a single template for the code snippets for all Given/When/Then - it might need to be split to give more flexibility and potentially allow configuring custom snippets.
  • There's also a single slice for all runtime steps - probably makes sense to keep it and still continue to refer to all Given/When/Then as a Step abstraction.
  • Not for this ticket, but Makefile didn't work OOB for me = more effort to contribute. Can we make it more flexible so it's easier to use with multiple installed versions of Go? It doesn't seem like a good idea to assume everyone has the required Go version, esp. when it's not the latest stable.

mirogta avatar Apr 05 '23 06:04 mirogta

There are tests for the Step definition having different meaning: Given/When/Then. Does it actually make sense? That made it a bit difficult to choose which keyword should the Step be replaced with, but I've made the best guesses. Should it even be allowed? E.g. if I have an assert (Then) then how would it make sense to use it in arrangement (Given)?

Could you give an example for this? The Given()/When()/Then() functions are built to only match their respective keyword in the feature files. With the Step() function, it could match no matter the keyword.

otrava7 avatar Apr 12 '23 10:04 otrava7

@mirogta One question, Given and When with this approach will match and understand the And too? For example:


Given 2 ducks and one hunter 
And the hunter is ready for the action -> This will still matching regardless Given, When or Then ?
When the hunter shoots one time
Then "1" ducks left alive

soulcodex avatar Apr 13 '23 07:04 soulcodex

Hi all, I created a PR that allows us to select a different snippet function for generating missing steps. The two options are now:

  • steps_func
  • gwt_func

steps_func is the default and old behaviour, gwt_func is a new function that generates the steps with the Given/When/Then keywords

I intend to add more snippet functions if this PR is merged.

For example: I personally would like the functions to be prefixed with the given/when/then keyword as well since Go does not use attributes. Also, I often work with methods on a TestFixture struct.

With this PR people can add snippet functions that match their workflow best.

crosscode-nl avatar Jan 03 '24 23:01 crosscode-nl

@mirogta One question, Given and When with this approach will match and understand the And too? For example:

Given 2 ducks and one hunter 
And the hunter is ready for the action -> This will still matching regardless Given, When or Then ?
When the hunter shoots one time
Then "1" ducks left alive

I'm not sure I understand your question exactly. The line with And should match, but not necessarily "regardless"…

The And is imho used for readability and it needs to know in which context it's used, whether it's a replacement for Given, When or Then. The same example without And should also work:

Given 2 ducks and one hunter 
Given the hunter is ready for the action -> "And" in this context would be a replacement for "Given"
When the hunter shoots one time
Then "1" ducks left alive

But to your point about "regardless", the following should be invalid:

Given 2 ducks and one hunter 
Then the hunter is ready for the action  -> "And" in this context cannot be a replacement for "Then", the Given-When-Then has a strict order
When the hunter shoots one time
Then "1" ducks left alive

mirogta avatar Jan 22 '24 10:01 mirogta