Software Quality Assurance & Testing Asked by Alexey R. on November 15, 2021
I do know that basically all Given
, When
, Then
and And
keywords in feature definition technically are not distinguished by Cucumber. But why does Cucumber have different annotations for the step definitions @Given
, @When
, @Then
, and @And
?.
What I am observing is either you have the code describing the step:
@When("^first operand = "(.+?)"$")
public void setFirstOperand(String firstOp){
firstOperand = Integer.parseInt(firstOp);
}
or you have the code:
@Then("^first operand = "(.+?)"$")
public void setFirstOperand(String firstOp){
firstOperand = Integer.parseInt(firstOp);
}
both execute the logic of the test in an identical way.
Is there any difference how Cucumber framework treats the code under those different annotations? I believe there should be some difference otherwise this architecture (when you have different entities intended to address the same logic) would not look pretty “object-oriented”.
The difference lays in design, not functionality
As there seems to be some dissatisfaction with the accepted and given answers, I want to wrap it up, risking to only add some noise to the thread.
The answer to your question is... only that Then "jada jada" is differentiated from Given "jada jada" and calling another part of your testing code respectively, although sharing the same name (trivial difference).
Jithu Paul wrote appropriately:
The idea of the BDD framework like cucumber is to enhance the knowledge of what is being tested to people outside the testing layer like the BAs [...] or product owners.
It is not meant to primarily (at all?) "bring functionality" in a technical sense (as different keywords in a programming language would) but to "translate" your testing framework to non-technical instances and vice versa (e.g. support tickets etc). The mentioned keywords only aim to deliver syntactical sugar to make it readable "as if it were English".
That said I want to show an example of how I differentiate between them:
Given describes preconditions (e.g. "I am a logged in User") - .. and therefore may involve many steps, like navigating to the log in form, filling in values, clicking a button, etc. This precondition comes with an expectation that could (should?) be checked against (~ a final assertion in the function itself).
When describes a single Step (e.g. "I click on the articles link") - .. and thus is not primarily part of the tested functionality. I rarely check them against expectations (as I would test code twice often). The main difference to the Given steps is that When steps are much more trivial. I put here everything that is crucial for the current feature only to not end up repeating myself.
Then steps validate an expectation (e.g. "I should see a list of articles) - .. and that means they are not at all as the prior two: They return true and false (instead of an action) and determine the progress and quality of your code "to the outer world".
Obviously, all the keywords do the same: executing (any) code. You could(and should not) write your tests using only one of them. (Again: Gherkin is written for non technical personas)
Finally, if you treat the steps as suggested, you Don't Repeat Yourself, and have a much more readable and maintainable codebase (which is important for developers to work fast and clean).
If you do view and controller testing for your own project as a developer, I would not suggest you to use cucumber at all, instead, use a more technical framework to lay out your specs. (I don't come from a Java perspective here, as I used cucumber only for ruby so far, but the principles are the same.) Under the hood, Cucumber uses another language, and maybe frameworks. Use them since you are familiar with them, unless you need to translate your specs, or to give non technical people the option to write their own (that you then had to implement).
Answered by randmin on November 15, 2021
It seems that your question was misunderstood several times and not even your comments fixed this situation. I think at least I got your question right - at least I find it quite clear: It's not about the DSL, it's about the annotations for test steps.
Unfortunately, I can't answer why cucumber actually has different annotations for step definitions, but I know why I would have designed the API with those different annotations if I had designed it.
I'm not at all an expert for cucumber but I find the way the semantics of Given
, as described in cucumber's Gherkin specification quite contradictory. It starts sensibly:
Given steps are used to describe the initial context of the system - the scene of the scenario. It is typically something that happened in the past.
Perfect! Clearly a precondition, right? Could mean if this precondition isn't fulfilled, the scenario simply doesn't apply.
The next sentence of the same description destroys this hope:
When Cucumber executes a Given step, it will configure the system to be in a well-defined state, such as creating and configuring objects or adding data to a test database.
That's definitely not what we call separation of concerns - I'd rather call it messing up concerns.
For configuring a system to be in a well-defined state we usually have setup tasks with @Before
annotations or whatever.
In natural English (I'm not a native speaker so I might be slightly wrong) Given
introduces a precondition. And that's exactly where we COULD benefit from a specific @Given
annotation (cucumber seems to have missed this chance): it could (and I think should) annotate a boolean function that indicates whether or not the test (all the When
s and Then
s as well as further Given
conditions) are applied or not.
In simpler words: ideally, tests would never fail if a precondition isn't fulfilled. This would introduce significantly enhanced flexibility regarding test data.
Back to natural language (well, somewhat semi-natural):
"Given you accepted the meeting. When the meeting starts, Then I expect you to be in the meeting room."
Here I'm saying that all the rest only applies if you accepted the meeting. If you didn't the meeting might not start and even if it starts I won't expect you to be in the meeting room.
And this is where the value of a specific @Given
annotation could come in: a test runner could ignore all tests or all outline records that don't match the precondition. In a similar manner as JUnit
deals with assumeThat
.
I could imagine that the designers of the API had something like this in mind. Maybe after the API design was finished, there wasn't enough time to implement it like this, or the people implementing the solution had a different opinion.
Since the test runner obviously isn't implemented in the way the different annotations suggest, I suppose it is what you seem to be perceiving: a design flaw.
Even worse this flaw leaks into the DSL. Because it means that the keywords have no specific semantics either.
And obviously enhanced semantics for the existing DSL and API can't be introduced without potentially breaking existing tests - or even more probable and even worse: hiding errors that existing tests now cover by abusive Given
semantics.
Sorry for having wasted so many words for again not answering your question. But at least now you have an answer that addresses your question - and you have found a fellow sufferer.
Answered by yaccob on November 15, 2021
The cucumber keywords like Given, When, And, But, Then are used to enhance the readability and understand ability of the scenario which the QA is planning to test in the scenario.
The idea of the BDD framework like cucumber is to enhance the knowledge of what is being tested to people outside the testing layer like the BAs and the developers or product owners.
The syntax of a typical scenarios is like as follows:
Scenario: Some determinable business situation
Given some precondition exists
And some other precondition exits
When some action by the actor
And some other action
And yet another action
Then some testable outcome is achieved
And something else have also happened
Answered by Jithu Paul on November 15, 2021
Typically you setup your scenario in the given step, this could be connecting to a service, loading its configuration, priming its fixtures
In the when step you have the principal action you are testing, this could be a user request or a service taking an action.
You could chain actions with and steps.
Finally the then step will verify the action occurred, this can be by asserting about the resulting data or state.
With good step design, you can reuse steps between features to increase coverage and efficiency.
This is best achieved with careful parameterization of the steps to make them extensible.
You can also use tables in your features to run a step multiple times with different data from the table rows each time.
You can also run the same steps with values hardcoded in to the feature lines.
Other than looping if you use tables there is no difference in how those functions are invoked by cucumber than any other. At least in most implementations I've seen but it may be different in yours. You could run it in a debugger and check.
Some custom tools like SpecFlow pass around all sorts of other objects and state to allow you to construct the scenario you are testing.
Answered by Amias on November 15, 2021
The problem Cucumber addresses is communication not architecture.
These keywords are just syntactical sugar, for the business user's understanding and readability. Technically there is no difference.
Having said that, the whole concept of Cucumber (BDD) is to have a common shared vocabulary(DSL) so all team members can communicate on the same level including non-technical people.
The value received is for the whole team in terms of improved communication by a shared vocabulary.
As far as coding is concerned,
A function's job is to return the current state of the application, it's test's job to determine (assert) it is positive or negative based on the given test scenario and pass or fail the test accordingly.
So a function can return the same state which might be determined positive/ or negative by the test script depending on the scenario it's currently validating.
Answered by Vishal Aggarwal on November 15, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP