Open Sydney-o9 opened 6 years ago
I think this is worth a shot - I've finished to work on a Proof Of Concept here. Feel free to let me know what you think.
Ultimately, I think to be able to improve further on all the points @jakzal, @stof & others made, it would be great to apply similar concepts from redux:
Dispatching actions via $this->store->dispatch()
for example, using reducers, etc and NOT updating the store directly as currently set-up.
This would avoid this:
@jakzal I don't see how it's simpler. What I see is lots of WTF moments trying to trace which step this variable came from.
This is correct.
There is an existing php-redux library so it would be possible to build on top of it easily - I haven't tried it.
These are simple concepts yet very powerful. This could actually leverage Behat test suite, not necessarily limited to Scenarios.
As mentioned, I've done a Proof of Concept for what was mentioned in my previous comment for you guys to have a think about.
I was summoned here by your comments referencing my username ;)
I didn't have time to look through all your work unfortunately. Let me share with you my recent thoughts on this topic. Perhaps it'll give you some ideas.
The approach I recently used involved a builder. Builder is stateful and gathers all the needed information as steps are invoked (mostly givens). Then, at some point one of the steps will use the information gathered by the builder to construct the object(s) we need to perform an action (probably a "when"). The builder is stateful, if it ever returns an object it's always a new instance (or an immutable object). This makes it easier to avoid the WTF moments, when object references are passed around and modified.
This worked well for my use case. It might not work for everyone though.
Hi @Sydney-o9,
(sorry didn’t saw your comment earlier…)
First of all, thanks for your well written well thought issue <3.
I’m a little too brainfucked right now to have a real well thought feedback, so this is my hot reaction to your issue ;)
Regarding your feature file proposal:
I see your point, and I feel it’s definitely more explicit from a developer point of view.
But, I am a bit more concerned from a non technical .feature
reader/writer point of view though. I have the feeling that your proposal might encourage to sneakily add some technicalities in the feature description (which I am strongly against).
The more near natural language the feature is, the better.
From this perspectives, I think I am more inclined to let the gherkin untouched for now.
That being said, the explicitness of what this extension brings seems to trigger lot of reactions and it’s definitely something we should improve, in this regard your proposition and @jakzal advices are very valuable :)
@vincentchalamon, any thoughts on this?
Regarding more flexibility when storing data to the store is definitely interesting (I’ll open another issue to discuss it).
Hi all,
I tried to understand all your points, so I hope I won't be out ot scope in my answer :-)
- Currently, the scenario is being shifted to in the Context classes when it should stay in the .feature files
- storeKeys are only made available in the context
The approach we wanted to share through this extension is to keep scenarios (.feature
files) non-technical, like @gorghoa said in the last comment. Introducing technical steps in the scenario will break this rule.
I invite you to have a look at Samuel Roze's conference, which describes this point: Behat is more than that.
It is not possible to store more than 1 instance in the store of the same type without having to keep track of the store keys used in the annotation provided
If I understand this point, you want to store several values on the same key in the store? Do you have any example for this case please? If so, this could be a great enhancement imo, if it doesn't break BC and doesn't make annotation usage too complex. Feel free to open a PR to propose it @Sydney-o9. What do you think of it @gorghoa?
reading the feature is not enough to know the state of the store (we should now the state of the store by reading the feature)
Same as first point: scenarios should be non-technical. If you want to know the context for your scenario, just explain it literally. For instance:
Scenario: A gorilla gives a banana to another gorilla
Given there are 2 gorillas
And there is a banana
When the gorilla gives the banana to another gorilla
Then the last gorilla has the banana
In this example, it's very easy to undertand the context, whatever is saved in the store. Technical points (like the state of the store) are out of scenarios and should be kept in the context.
Dispatching actions via $this->store->dispatch() for example, using reducers, etc and NOT updating the store directly as currently set-up.
This is, imo, a really good idea & improvement! I'm just wondering if it wouldn't be overkill, as the main goal of this extension is to store data between steps. I can't see any case where dispatch the store would be useful, could you print an example @Sydney-o9 please? What do you think of that feature @gorghoa?
@Sydney-o9 :
Dispatching actions via $this->store->dispatch() for example, using reducers, etc and NOT updating the store directly as currently set-up.
@vincentchalamon :
I'm just wondering if it wouldn't be overkill
My exact thoughts @vincentchalamon ;)
I fear the complexity this would add to the extension, maybe even counterproductive with the explicitness we aim for.
My first thoughts is maybe this should live userland, in your own Contexts. I guess it wouldn’t be that hard to abstract the $this->scenarioState->provideStateFragment('scenarioBanana', $banana);
within some custom logic (for instance with some kind of php-redux, I guess you could call provideStateFragment
in an action).
@Sydney-o9
It is not possible to store more than 1 instance in the store of the same type without having to keep track of the store keys used in the annotation provided
Could you elaborate this point? I’m not sure to understand exactly what you mean
I really like the idea behind this extension.
(Even though most of the time, if you are at Level 3 of the Richardson Maturity Model, you can use HATEOS & Hypermedia to follow
_links
but this is not always possible - hence the necessity of a solution which your extension solves really well.)This discussion was very interesting to me and I think you guys are solving something important.
In regards to readability, I wonder if one might consider the following as on top of what was discussed, I think:
.feature
filesIt should be the same for the store.
How about using the gherkin language instead?
This would be more explicit, and would allow to identify the store keys easily. Now, we know all objects being stored start with
@
(it could be any notation) but when reading the test, it is more readable and really takes on the power of your extension which is the ability to store stuff between contexts easily.You can then imagine the following when things get tricky:
Basically I think being explicit is key and this should never happen:
It should be
Also, in regards to this:
It could be:
ScenarioStateAutosave
would autosave the variables to the store based on what is returnedScenarioStateAutoload
would autoload the variables to the store based on the keys provided