Upgrade to Pro — share decks privately, control downloads, hide ads and more …

E2E testing Single Page Apps and APIs with Cucu...

E2E testing Single Page Apps and APIs with Cucumber.js and Puppeteer

Presented at London Node User Group April 2018 meetup

Paul Jensen

April 25, 2018
Tweet

More Decks by Paul Jensen

Other Decks in Programming

Transcript

  1. SPAs are a popular approach API Web App Mobile App

    3rd Party API consumer Databases
  2. But testing them is not simple API Web App Mobile

    App 3rd Party API consumer Databases
  3. E2E Testing a SPA needs • The Single Page App

    • The API that serves the SPA • The databases that serve the API • The data in the databases for testing
  4. Today I want to talk about a testing strategy* *

    there are many testing strategies
  5. Step 2 Create a folder in your app called “features”.

    We will put cucumber-related files and folders in here. features
  6. Step 3 Meet with your product owner and talk about

    a feature to implement. Talk about how that feature works from the perspective of the user, and write notes.
  7. Step 4 Create a file in the features folder, say

    for example delete_user.feature. Type the notes from earlier into that feature file, and write them in a format like the example here.
  8. Step 5 The feature file we created can be parsed

    by Cucumber. Go to the terminal, and run this command on the right. Cucumber will look for files in the features folder, execute them, and print out results.
  9. Step 5 - step definitions When executing the feature file,

    Cucumber will try to match the lines in the feature file to step definition functions. If no step definition functions are found, it will print out example code to insert. step definition files
  10. Step 5 - step definitions When a step contains one

    or more words in quotes, Cucumber’s parser will extract out that quote and pass it to the step definition function as a variable. It also does this for numbers as well.
  11. Step 6 Create a folder called “step_definitions” inside of the

    features folder. Then create a file, say for example “common_steps.js” inside the step_definitions folder, and put the step definitions code in there. Cucumber will find this code and execute it upon subsequent test runs step_definitions common_steps.js
  12. Step 7 We fill in the step definition functions with

    code that performs an action, such as: - Clicking on a button in the web app - Checking that a user is logged into an app - Querying the database to check that a record was entered into a table
  13. Step 7 Our tests should fail, but as we write

    the application’s code, they will start to pass. We can then use this safety net to refactor the code and make bigger changes to the application. Fail Pass Change
  14. A Node.js library that provides a high- level API for

    controlling Google Chrome (or Chromium) via the DevTools protocol
  15. Puppeteer can run the web browser in either full mode

    (browser windows), or headless mode (no browser windows)
  16. You can use it to… • Take screenshots of web

    sites • Create PDF files from web pages • Crawl a SPA and generate pre-rendered content, such as scraping a major ticketing site. • Power web spiders that fill in forms automatically • Get a timeline trace of a web site loading, and measure performance
  17. Install Puppeteer will download a version of Google Chrome/ Chromium

    that works with the library as well as your OS. It’s a much simpler experience than trying to install Selenium.
  18. Puppeteer • You can use it as part of your

    testing strategy • It can be used inside integration services like CircleCI • You can even use it in AWS Lambda functions
  19. Puppeteer is loaded into Cucumber’s world.js file, a global context

    that all step definitions can access. The world.js file lives inside the features folder, and is loaded automatically when running Cucumber
  20. Dashku • A dashboard app • 1st version was built

    back in 2012 as a Realtime web app using a framework called SocketStream • The new version is being built as a SPA and API, with React on the frontend, and Express/MongoDB/Redis on the backend. • This time I wanted to build it using BDD from the start
  21. The E2E repo needs to load the SPA and the

    API, and do setup/teardown But how do we do that?
  22. NPM • It isn’t just a package manager • You

    can use it to stitch together a couple of dependencies in order to achieve a larger goal • It can coordinate the setup and teardown of multiple components for testing via npm script commands • Let me show you the package.json for the dashku- integration repo
  23. I can then point to local copies of the web

    and api repos with npm link
  24. Now when I create a new product feature, I can

    write the tests in Cucumber, then implement the feature in the SPA, and then in the API
  25. And when I need to run the tests, I can

    coordinate the setup across the components from one place
  26. I then load the Web and API repos in a

    world.js file from earlier.
  27. Dashku uses MongoDB & Mongoose* * but I am considering

    PostgreSQL and Objection.js instead
  28. How do I get Cucumber to directly put data into

    the database and clean it up during test runs?
  29. Inserting data • Seeding data happens as part of the

    Cucumber feature scenarios • Cucumber then loads the step definition function that matches. • The step definition code is abstracted away, for reasons that will become clearer later on. features/Login.feature features/step_definitions/common_steps.js
  30. The other benefit is that you can use Node’s Async/Await

    to combine step definitions for a single step
  31. Ideally we don’t want to repeat those 7 lines every

    time we want to login a user in a Cucumber scenario. That would make reading those feature files…
  32. Selecting elements in the page to click, fill in and

    check that they’re there • You can use CSS selectors to get at elements • I have a nice large list of CSS selectors that are referenced from a JS object tree. • XPath support will be coming in the next release of Puppeteer (~ 3 weeks time)
  33. If you want to test across multiple browsers, do look

    at using Selenium or webdriver.io in place of Puppeteer
  34. There’s a chapter on it in my book Also in

    Mandarin Chinese! Thanks to Goddy Zhao for translating