bdd In 2019
cypress & cucumber
bene@theodo.co.uk
Ben Ellerby
Unit
Integration
End to End
Domain-Driven
DESIGN
DDD
Evans, E., 2004. Domain-driven design: tackling complexity in the heart of software. Addison-Wesley Professional.
Ubiquitous Language
GIVEN, WHEN, THEN
BDD
Given some context When some action Then some result
GIVEN, WHEN, THEN
BDD
Given the account has £10 When the customer requests £20 Then cash is not dispensed And an error message is displayed And the card is returned
Narrative
BDD
Story: One line description As a ROLE In order to GOAL I want to BENEFIT
Cypress
Cypress
Text
Cypress
Cypress
Cypress
Cypress does not use Selenium
Cypress
describe('My First Test', function() {
it('Does not do much!', function() {
expect(true).to.equal(false)
})
})
Cypress
describe('My First Test', function() {
it('Does not do much!', function() {
expect(true).to.equal(false)
})
})
Cucumber
www.cucumber.io
Provides the DSL for writing scenarios with the Gherkin syntax
Helping to provide living documentation
Cypress + Cucumber
https://github.com/TheBrainFamily/cypress-cucumber-preprocessor
+
Cypress + Cucumber
import { Then } from "cypress-cucumber-preprocessor/steps";
Then(`I see {string} in the title`, title => {
cy.title().should("include", title);
});
https://github.com/TheBrainFamily/cypress-cucumber-example
Cypress + Cucumber
FIXTURES
To stub or not to stub, that is the question....
Cypress + Cucumber
Not Stubbing
Cypress + Cucumber
Stubbing
Cypress + Cucumber
NOT Stubbing
Cypress + Cucumber
NOT Stubbing
Cypress + Cucumber
Stubbing
- Start a cy.server() (Allows stubbing)
- Provide a cy.route() (Makes a stub)
Cypress + Cucumber
cy.server() // enable response stubbing
cy.route({
method: 'GET', // Route all GET requests
url: '/users/*', // that have a URL that matches '/users/*'
response: [] // and force the response to be: []
})
Stubbing
Cypress + Cucumber
Stubbing
"A fixture is a fixed set of data located in a file that is used in your tests."
Fixture:
Cypress + Cucumber
cy.server()
/// define the fixture
cy.fixture('activities.json').as('activitiesJSON')
// use the fixture, via alias (advanced concept of Cypress)
cy.route('GET', 'activities/*', '@activitiesJSON')
Stubbing
Cypress + Cucumber
iNTERCEPT dELAY
Cypress
Tests
API
Stub
Cypress + Cucumber
cy.server()
cy.route('tagdefs/*', 'fixture:tagedefs').as('getTagDefs')
cy.route('users/*', 'fixture:users').as('getUsers')
// page reauires routes via HOCs
cy.visit('http://localhost:3333/user/list')
// wait on routes via aliases
cy.wait(['@getTagDefs', '@getUsers'])
// will only run after network requests
cy.get('h1').should('contain', 'User List Page')
cy.get('li').should('contain', 'User Name 1')
Stubbing
Cypress + Cucumber
Scenario: #471 - /user/list - Filter by non-existing user
When I type "BobMarley" into the list filter search bar
Then I do see "No results" in the list filter items
And I do not see "Bob Marley" in the list filter items
Scenario
Cypress + Cucumber
Background: I am on /user/list
Given I have an API with users
And I have an API with tag defs
And I am on "/user/list"
And I wait for "getUsers"
And I wait for "getTagDefs"
Scenario Background
Cypress + Cucumber
Given("I have an API with users", () => {
cy.server()
cy.fixture("users.json").as("users")
cy.route("**/user/list", "@users").as("getUsers")
})
API Step Def
Cypress + Cucumber
Given("I wait for {string}", alias => {
cy.wait(`@${alias}`)
})
Waiting step Def
Cypress + Cucumber
cy.server()
cy.route('search/*', [{ item: 'Book 1' }, { item: 'Book 2' }]).as('getSearch')
cy.get('#autocomplete').type('Book')
// this yields us the XHR object which includes
// fields for request, response, url, method, etc
cy.wait('@getSearch')
.its('url').should('include', '/search?query=Book')
ASSERTIONS ON STUB
ANy quESTIONS
BDD Workshop (Cypress Fixtures)
By Ben Ellerby
BDD Workshop (Cypress Fixtures)
The talk was given at the QE-Roundabout Meetup in London 12/02/19.
- 1,412