Slide 1

Slide 1 text

#MerpayTechFest Session Title Frontend Testing: Cypress as a Testing Platform Wilson Lau Frontend Engineer, Merpay

Slide 2

Slide 2 text

#MerpayTechFest Frontend Engineer, Merpay Wilson Lau Originally from Canada, I joined Merpay in the beginning of 2020 as a frontend engineer. Since then, I've worked across a number of Merpay's web products - including our internal merchant and customer Support tools, our Merpay partner site, and new merchant application process. Currently, I'm leading the push for better frontend testing within Merpay, and hopefully beyond!

Slide 3

Slide 3 text

#MerpayTechFest Background: Merpay 2019.2–3 iD Payments/ QR Code Payments Available at 2.06 million iD and Merpay merchants nationwide, including convenience stores, restaurants, drug stores, and fast food *As of March 31, 2021 (merchants with both iD/QR counted once only) 2020.7 Merpay Smart Payments Allows users to defer payment for items based on past usage of Mercari and Merpay Online Payments Enables use of Merpay for not only offline purchases, but online as well 2020.9 Send/receive Enables users to send their Merpay balance/points to family and friends No-contact service 2019.4–5 Growing Wallet Enables users to utilize their Merpay balance on the peer-to-peer investment service Funds *Second investment fund went live in January 2021 2020.11 2021.3 Shared d Payment/ Merpay QR code Enables use of single QR code for both d Payment and Merpay Virtual card Enables users to easily issue a card number which can be used to pay using Merpay balance at many online stores Identity verification using Japan’s Individual Number Card (JPKI) Launched support for identity verification using Japan’s public Individual Number Card identification service (JPKI) Merpay Smart Payments (fixed-amount) Allows for “fixed-amount payments,” whereby users pay in installments from the following month onwards Mercari Donation Enables donation of Merpay balance, charged from Mercari sales balance or bank account, etc., to local governments and other organizations of the user’s choice

Slide 4

Slide 4 text

#MerpayTechFest Background ● Reduce manual QA time requirements ● Increase confidence when doing maintenance tasks and refactoring ● Onboarding new team members / learning new products ○ Using tests as a reference, new members can quickly understand specs ● Increase velocity in new feature development ○ Fully mocked backend APIs lets us develop at the same time as backend ○ Implementation-agnostic tests allows us to write tests and product code simultaneously ● Reduce bugs and issues in general How do we maintain our development velocity?

Slide 5

Slide 5 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Integration Testing E2E Regression Testing Accessibility Testing Shared Utilities Performance Testing Component Testing Visual Regression Testing Reporting / Dashboards FUTURE

Slide 6

Slide 6 text

#MerpayTechFest Cypress Testing Stack Cypress

Slide 7

Slide 7 text

#MerpayTechFest Cypress What is Cypress?

Slide 8

Slide 8 text

#MerpayTechFest Cypress Why Cypress instead of other testing libraries? ● Less mocking; real browser environment ○ Using jest-based testing libraries that rely on jsdom requires a lot of mocking out of key components of our application ○ Not true integration tests with so many components mocked out ○ Significant issues with asynchronous behaviour ● Immediate visual feedback ○ Easier to debug tests when there is visual feedback available ○ Can develop in a TDD-like way and create different scenarios ● Enforces testing of behaviour instead of implementation

Slide 9

Slide 9 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks

Slide 10

Slide 10 text

#MerpayTechFest export default function handler( req: GetUserRequest | null = null, modification: Partial ): GetUserResponse { return { id: req.user.id || “default-id”, name: “Test User", email: “[email protected]”, ...modification } } API Mocks Full set of type-safe mocks lets us setup any scenario possible

Slide 11

Slide 11 text

#MerpayTechFest API Mocks ● Our mocks are response generator / request handler functions written in TS ○ Every mock returns a default response, and accept a second parameter that allows for modifications of the response ○ Optionally, it’s possible to write custom handlers that respond different based on request body / query parameters, which Cypress makes available ● Combinations of these mocks are used as the ‘setup’ before loading a page ○ cy.intercept also allows us to change the responses throughout a test ● These mocks can also be used on local development – we have implementations using mock service workers / custom node.js server for mocking Full set of type-safe mocks lets us setup any scenario possible

Slide 12

Slide 12 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Shared Utilities

Slide 13

Slide 13 text

#MerpayTechFest Shared Utilities describe(“Form”, () => { beforeEach(() => { cy.mock(UserAPI.getUser, { email: ‘[email protected]’ }); }); it(“should render the form properly”, () => { cy.getByTestId(“testForm”) .assertTextInput(“Email”, “[email protected]”, { placeholder: “Email” }) .assertSelect(“True/False”, null, { values: [“True”, “False”] }) .updateTextInput(“Email”, “[email protected]”); }); }); We write custom utilities to make tests easier to read and write

Slide 14

Slide 14 text

#MerpayTechFest Shared Utilities ● Make tests easy to read ○ Tests are very readable and can act as a specification for the product ○ Liberal use of Cypress chaining pattern to group sections together ○ Use of file structure, sections and test descriptions for organization ● Make tests easy to write ○ Abstractions enforce patterns in both the test code and product code ○ Fairly strict test structure helps us make sure that we’re testing ○ Tests are based on visible DOM elements as much as possible We write custom utilities to make tests easier to read and write

Slide 15

Slide 15 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Shared Utilities Reporting / Dashboards

Slide 16

Slide 16 text

#MerpayTechFest Reporting & Dashboards What gets measured get managed ● All of our tests generate their own reports ○ @cypress/code-coverage (nyc reporters) ○ Custom cy.task / cy.log reports for a11y ● Tests are run by cron jobs either once a day / on every commit in CircleCI ● All test runs done in CircleCI have a job that uploads these reports ○ Upload all test reports via GCP Cloud Logging / BigQuery ○ Generate dashboards using Looker ■ Individual project dashboards ■ Overview dashboards for type of test

Slide 17

Slide 17 text

#MerpayTechFest Reporting & Dashboards

Slide 18

Slide 18 text

#MerpayTechFest Reporting & Dashboards

Slide 19

Slide 19 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Shared Utilities Reporting / Dashboards E2E Regression Testing

Slide 20

Slide 20 text

#MerpayTechFest 1. E2E Regression Testing E2E Testing in live test environment ● We build and maintain E2E regression tests in collaboration with our QA team ○ These tests do not mock anything at all and run in our test environment and interface with backend microservices deployed in test. ○ Tests are run during QA period, before every release ● In order to create test data: ○ QA team maintains test requests as Postman JSON – we built a helper to use Postman JSON to create requests in Cypress. ○ There is also some existing test data that we use if we do not feel like we need to create new data for the test.

Slide 21

Slide 21 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Shared Utilities Reporting / Dashboards E2E Regression Testing Integration Testing

Slide 22

Slide 22 text

#MerpayTechFest 2. Integration Testing What is frontend integration testing? ● Integration of all frontend code (logic, store, components) ● API Responses are fully mocked, but nothing else. ○ Input (Mocks): API Responses + user actions in the DOM ○ Output (Assertions): Rendered DOM & API Requests ● We test behaviour, not implementation: ○ Rendering: Given a response, do we render the correct elements? ○ Permissions: Given a response + auth, is what is displayed / allowed correct? ○ Validation: Do we correctly validate users’ inputs and actions? ○ Actions: Does a given user flow generate the correct request?

Slide 23

Slide 23 text

#MerpayTechFest 2. Integration Testing Example Test Structure describe(“/dashboard”, () => { describe(“rendering:”, () => { it(“should render the form correctly”, () => { ... }); }); describe(“validation:”, () => { it(“should validate the name input correctly”, () => { ... }); it(“should not be able submit the form when errors exist”, () => { ... }); }); describe(“actions:”, () = { it(“should be able to submit the form successfully”, () => { ... }); it(“should be able to navigate to the next page correctly”, () => { ... }); }); });

Slide 24

Slide 24 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Shared Utilities Reporting / Dashboards E2E Regression Testing Integration Testing Accessibility Testing

Slide 25

Slide 25 text

#MerpayTechFest 3. Accessibility Testing ● axe is one of the standard accessibility tests that we’ve chosen to adopt ● cypress-axe is convenient integration with some custom code ○ Render a full page using standard mocked response ○ Run axe tests against the rendered page ○ Use cy.task and cy.log to generate our own custom reports ● Measurements ○ Number of accessibility violations per page ○ % of pages passing threshold number of accessibility violations ● Custom cypress commands / config can be shared between all projects cypress-axe as key integration

Slide 26

Slide 26 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Shared Utilities Reporting / Dashboards E2E Regression Testing Integration Testing Accessibility Testing Performance Testing

Slide 27

Slide 27 text

#MerpayTechFest 4. Performance Testing ● We’ve chosen to use Lighthouse as our performance testing tool ● Cypress allows us to run these tests in multiple environments: ○ Build app as SSR vs SPA ○ Use mocked APIs vs using APIs in test environment ○ Allows us to diagnose performance issues in more detail ● Measurements ○ Typical performance metrics: LCP, TBT, CLS, TTI ○ Metrics measured on a per-page level cypress-audit & cypress-lighthouse

Slide 28

Slide 28 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Integration Testing E2E Regression Testing Accessibility Testing Shared Utilities Performance Testing Visual Regression Testing Reporting / Dashboards FUTURE

Slide 29

Slide 29 text

#MerpayTechFest 5. Visual Regression Testing (Future) ● Current tests do not give us any feedback about any unwanted visual changes ● QA visual inspections are still required ● cy.screenshot can be used to produce screenshots of each page ○ Render a full page using standard mocked response ○ Take screenshots of the page ○ Use library to diff the screenshots ● Tried using reg-cli for comparisons, but still have not standardized approach ● Some other options to consider: applitools, cypress-plugin-snapshots, cypress-visual-regression, cypress-image-diff Currently investigating various options

Slide 30

Slide 30 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Integration Testing E2E Regression Testing Accessibility Testing Shared Utilities Performance Testing Component Testing Visual Regression Testing Reporting / Dashboards FUTURE

Slide 31

Slide 31 text

#MerpayTechFest 6. Component Testing (Future?) Introduced in v.7.0.0 in April 2021 (in alpha) ● Potential alternative to Storybook + Jest ● Mount components instead of rendering an entire page ○ Visually inspect component in a browser environment ○ Use Cypress query / action APIs to manipulate and test various actions ○ Use Cypress assertions to write tests ● Cypress is building out support for frameworks to mock global variables ○ Ex. $store, $i18n, etc. ● Still early and missing a lot of features available in Storybook

Slide 32

Slide 32 text

#MerpayTechFest Cypress Testing Stack Cypress API Mocks Integration Testing E2E Regression Testing Accessibility Testing Shared Utilities Performance Testing Component Testing Visual Regression Testing Reporting / Dashboards FUTURE

Slide 33

Slide 33 text

#MerpayTechFest Thank you! Any questions? @wilsonplau @wilsonplau