DEV Community

Ramu Narasinga
Ramu Narasinga

Posted on • Originally published at thinkthroo.com

Testing in Umami codebase - Part 1.3

Inspired by BulletProof React, I applied its codebase architecture concepts to the Umami codebase.

This article focuses only on the testing strategies used in Umami codebase.

Prerequisites

  1. Testing in Umami codebase — Part 1.0

  2. Testing in Umami codebase — Part 1.1

  3. Testing in Umami codebase — Part 1.2

In part 1.1, we reviewed the website.cy.ts. It has the test cases for adding, editing and deleting a website. In this part 1.2, we reviewed the login.cy.ts test cases. In this part 1.3, we review the api-website.cy.ts

I found the following test cases defined in api-website.cy.ts

  1. Creates a website for user.

  2. Creates a website for team.

  3. Creates a website with a fixed ID.

  4. Returns all tracked websites.

  5. Gets a website by ID.

  6. Updates a website.

  7. Updates a website with only shareId.

  8. Resets a website by removing all data related to the website.

  9. Deletes a website.

I would be more interested to learn about fixtures because I saw it some of the test cases and also review the pattern used to make API requests within a test case.

Let’s choose a test case: #1, this demonstrates how a fixture is used.

What is a fixture in Cypress?

Fixture loads a fixed set of data located in a file. 

Syntax

cy.fixture(filePath)
cy.fixture(filePath, encoding)
cy.fixture(filePath, options)
cy.fixture(filePath, encoding, options)
Enter fullscreen mode Exit fullscreen mode

Usage

cy.fixture('users').as('usersJson') // load data from users.json
cy.fixture('logo.png').then((logo) => {
  // load data from logo.png
})
Enter fullscreen mode Exit fullscreen mode

Check out docs related to Fixtures.

Creates a website for user

You will find the following code at L30 in api-website.cy.ts.

it('Creates a website for user.', () => {
  cy.fixture('websites').then(data => {
    const websiteCreate = data.websiteCreate;
    cy.request({
      method: 'POST',
      url: '/api/websites',
      headers: {
        'Content-Type': 'application/json',
        Authorization: Cypress.env('authorization'),
      },
      body: websiteCreate,
    }).then(response => {
      websiteId = response.body.id;
      expect(response.status).to.eq(200);
      expect(response.body).to.have.property('name', 'Cypress Website');
      expect(response.body).to.have.property('domain', 'cypress.com');
    });
  });
});
Enter fullscreen mode Exit fullscreen mode

I see the cy.fixture, this loads the websites json from the fixtures/websites.json

{
  "websiteCreate": {
    "name": "Cypress Website",
    "domain": "cypress.com"
  },
  "websiteUpdate": {
    "name": "Cypress Website Updated",
    "domain": "cypressupdated.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

cy.request API is used to send a POST request to the backend. This fixture data is used as the payload.

About me:

Hey, my name is Ramu Narasinga. I study codebase architecture in large open-source projects.

Email: ramu.narasinga@gmail.com

I spent 200+ hours analyzing Supabase, shadcn/ui, LobeChat. Found the patterns that separate AI slop from production code. Stop refactoring AI slop. Start with proven patterns. Check out production-grade projects at thinkthroo.com

References:

  1. https://github.com/umami-software/umami/blob/master/cypress/e2e/api-website.cy.ts

  2. https://docs.cypress.io/api/commands/fixture

  3. https://github.com/umami-software/umami/blob/master/cypress/fixtures/websites.json

Top comments (0)