Don't get stuck using Cucumber to make use of the keywords Given/When/Then
Many people still think that using Cucumber is the solution for non-technical people to start writing automated tests since you write the specification of how the software should behave in a natural language, and that specification can be run to test the system.
However, for such a natural language to function as an automated test script, we need code that interprets such language (Given/When/Then). That is, the natural language layer is a high-level abstraction level, while the code that interprets it is the โlow levelโ.
Often in Cypress discussion groups I see people asking for help with the Cucumber plugin integration, bugs and other issues which could have been completely avoided if Cucumber weren't being used in the first place.
Then you tell me, "But the test is so readable when I use the keywords Given/When/Then."
And I answer you: "Nothing prevents you from continuing to use these keywords without using Cucumber."
Let's see how?
Imagine an example of a web search engine.
In BDD (behaviour-driven development) we would have the following requirement:
Feature: Web search engine
As a world-wide web user
I want to search for subjects of my interest
To deepen my knowledge
In Gherkin, we could think of the following scenarios:
Scenario 1: Search by typing a term and clicking the magnifying glass
Given I access the search engine page
When I type a term and click on the magnifying glass
Then I see a list of results about the term I was looking for
Scenario 2: Search by typing a term and pressing ENTER
Given I access the search engine page
When I type a term and press ENTER
Then I see a list of results about the term I was looking for
Now, let's see an example where I covered such scenarios with Cypress without using Cucumber, but at the same time, without losing the use of the keywords Given/When/Then.
/* search.spec.js
*
* As a world-wide web user
* I want to search for subjects of my interest
* To deepen my knowledge
*/
describe('Web search engine', () => {
context('Given I access the search engine page', () => {
beforeEach(() => {
cy.visit('https://duckduckgo.com')
})
context('When I type a term and click on the magnifying glass', () => {
beforeEach(() => {
cy.get('#search_form_input_homepage')
.type('cypress')
cy.get('#search_button_homepage')
.click()
})
it('Then I see a list of results about the term I was looking for', () => {
cy.get('.results .result')
.should('have.length', 11)
})
})
context('When I type a term and press ENTER', () => {
beforeEach(() => {
cy.get('#search_form_input_homepage')
.type('cypress{enter}')
})
it('Then I see a list of results about the term I was looking for', () => {
cy.get('.results .result')
.should('have.length', 11)
})
})
})
})
And this is the result of the tests after running them in headless mode.
Web search engine
Given I access the search engine page
When I type a term and click on the magnifying glass
โ Then I see a list of results about the term I was looking for (4173ms)
When I type a term and press ENTER
โ Then I see a list of results about the term I was looking for (1973ms)
In other words, I still have the keywords Given/When/Then, my tests are still legible, and I haven't wasted a single minute integrating Cypress with Cucumber. So easy!
By the way, recently, I talked about "Writing Cypress Tests Without Cucumber," where I went beyond the usage of the keywords Given/When/Then, also showing how to run the same test based on a pre-defined list of data and how to run tests using tags, all without Cucumber. Check it out on YouTube.
Curious and want to learn more about testing automation with Cypress? Check out my online courses on Udemy.
๐ Until next time and happy testing!
This post was originally published in Portuguese at the Talking About Testing blog.
Top comments (8)
Hi Walmyr, nice. Curious how this works with common steps ?
Does it still reference the order of running the steps from the feature files or itโs run as per the order in your spec file?
Hi Richard, in this example there's no feature files, only spec files.
And when there are steps that are the same for more than one test, what I do is to create a
context
, and inside of thecontext
I use abeforeEach
hook, as shown in the content.I hope this clarifies things, if not, please let me know.
Thank you. Will need to give it a try ๐๐๐พ
For other examples, take a look at this gist gist.github.com/wlsf82/0110f4455a6....
This is the code of my talk at Global Tester's Day 2021, and the slides can be found here slideshare.net/walmyrlimasilvafilh....
Thank you ๐๐พ๐
This is neat! Great post as always, Walmyr!
Thanks Cecelia, I'm glad you liked it!