Using backend factories during frontend testing

Written by Julia GrabosSoftware Engineer, Tines

Published on April 21, 2021

This article was posted more than 18 months ago.

When constructing end-to-end tests for web applications there are many areas which can prove problematic and can discourage users from committing to writing them at all. One of those areas is setting up the system with test data. We have found that by sharing our backend fixture library with the frontend, we can side-step many of these problems and get better quality E2E tests.

When carrying out end-to-end tests we test the data that flows through the application in response to user actions; we test the network requests made and received by the client and the web server and we test the data created and destroyed during interactions of the various services. The areas touched during the execution prove that the application works as expected and in a consistent manner: correct and expected data is shown to the user in response to their actions.

(Our) End-to-end manifesto 

End-to-end testing is the closest approximation to how users interact with our application and a contrast to functional/component testing which tests the behaviour of isolated units. Such a test should be indistinguishable from a real user interacting with the system. Due to their repetitive nature, automating these tasks is essential to achieve the goal successfully.

Some of the challenges posed by the task of creating test data are traditionally solved by approaches of stubbed objects or snapshots of the current state of the application. Both approaches break the philosophy of what an end-to-end test is. In one, we fail to test the system-database interaction and in the other, we fail to create a real user-system interaction indistinguishable from a real user’s actions.

Data Factories and FactoryBot 

As the title suggests, the proposed solution to solve the challenge of creating appropriate and realistic data that aligns with our system’s expectations will use a fixture factory library https://github.com/thoughtbot/factory_bot, for a Ruby on Rails backend. Counterparts in other languages are available:

Over the years, the use of FactoryBot has become the de facto for backend testing in Rails, but projects which share data fixtures with the frontend are not a common sight. While it’s very standard to use a factory library to set up more backend focused tests, using this library in our end-to-end testing ensures that the data created in our E2E suite is always correct as it is driven by the backend fixtures and guarantees all the same validation rules are obeyed akin to production data created during real user interaction.

E2E testing in the context of a web app is usually driven by automated browser testing and a multitude of javascript frameworks are available in today’s market for this purpose. At Tines, the tool of choice is https://playwright.dev/. We use FactoryBot to create the data we want for our tests, without having to stub objects or take snapshots of the application. Instead, using FactoryBot, we make requests to our backend in the setup stage of the test, creating the objects we require for our test. The test then proceeds, exercising real APIs, creating database records, and so on… At the end of the tests, when the network connection with our system is torn down, the database is flushed of the objects created with FactoryBot.

// makeRecord helper used to create the data object in the test
function makeRecord(
    nameAndTraits: string | string[],
    args: Record<string, unknown> = {}
): any {
    return new Promise((resolve) =>
        fetchInPage(page, Paths.makeRecord(), {
            nameAndTraits,args,
        }).then(([statusCode, json]: [statusCode: number, json: unknown]) => {
            if (statu