DEV Community

Cover image for Reusing Dynamic Values in Cypress Tests: Store Once, Reuse Anywhere
Sehani Chathurangi for Cypress

Posted on

Reusing Dynamic Values in Cypress Tests: Store Once, Reuse Anywhere

In test automation, maintaining and reusing state between test cases is essential for creating efficient, end-to-end workflows. When writing Cypress tests that interact with APIs, it's common to receive dynamic data from a response—such as an ID, token, or reference number—that you'll need to use in a later request. Instead of hardcoding or repeating logic, Cypress allows you to store these values temporarily during the test run and reuse them wherever needed.

Let’s explore how to do this in a clean and efficient way.

Why Store Values Dynamically?

Many real-world scenarios involve multi-step processes where the output of one step is the input for the next. For instance:

  • A request may return an identifier (id) that’s required for the next API call.
  • A system may provide an access token that must be included in subsequent headers.
  • You might need to retrieve the status of a resource using a previously returned reference.

By reusing these variables, you:

  • Reduce redundancy: Avoid recreating the same data in every test.
  • Improve performance: Skip repetitive setup steps.
  • Mimic real-world workflows: Simulate multi-step user journeys.

01.Use Cypress.env() to Store and Reuse Data

Cypress provides a convenient way to store values in memory using Cypress.env() during a test run.

Store the Value

When you receive a value from an API response, you can store it like this:

cy.request('POST', 'your-api-url', requestBody).then((response) => {
  const dynamicId = response.body.id;
  Cypress.env('dynamicId', dynamicId); // Save it temporarily
});
Enter fullscreen mode Exit fullscreen mode

Reuse It in Another Request

You can then access that value in a later test step:

cy.request({
  method: 'GET',
  url: `your-api-url/${Cypress.env('dynamicId')}`,
  headers: {
    Authorization: `Bearer yourAccessToken`,
  },
}).then((response) => {
  expect(response.status).to.eq(200);
  // more assertions
});
Enter fullscreen mode Exit fullscreen mode

Example with Tokens

Here’s how to store an access token received from an authorization request:

cy.request('POST', 'token-url', credentials).then((response) => {
  const token = response.body.access_token;
  Cypress.env('accessToken', token); // Stored in memory
});
Enter fullscreen mode Exit fullscreen mode

Use it later:

cy.request({
  method: 'GET',
  url: 'api/secure-data',
  headers: {
    Authorization: `Bearer ${Cypress.env('accessToken')}`, // Used here
  },
});
Enter fullscreen mode Exit fullscreen mode

02.Using Test-Specific Variables

For data needed only within a single test file, use closures (e.g., let variables).

Example: Reusing a Resource ID

describe('Reusing ResourceID Tests', () => {
  let resourceId; // Accessible across all tests in this describe block
  it('Creates a Resource', () => {
    cy.request('/resources', { method: 'POST' }).then((response) => {
      resourceId = response.body.id; // Assign ID
    });
  });
  it('Validates the Resource', () => {
    cy.request(`/resources/${resourceId}`).then((response) => {
      expect(response.status).to.eq(200);
    });
  });
});
Enter fullscreen mode Exit fullscreen mode

03. External Storage (Files, Databases)

For cross-suite or cross-run persistence, save data to files (e.g., JSON) or databases. Use this sparingly, as it introduces external dependencies.

Good Practices

  • Use Cypress.env() for temporary values within the same test suite.
  • Do not use Cypress.env() as a way to persist values between test files.
  • Store static configuration in cypress.env.json, but store dynamic values using Cypress.env() at runtime.
  • Clean Up State: Delete test data after runs (e.g., in after hooks).
  • Avoid Hardcoding Values: Use environment variables or configuration files for URLs, keys, etc.
  • Handle Asynchronous Flows: Use cy.wait() or retry logic if systems need time to process data.

Summary

Storing dynamic data during test execution helps avoid hardcoding and keeps your Cypress tests clean and reliable. By leveraging Cypress environment variables, closures, or external storage, you can build robust test suites that minimize redundancy and maximize efficiency. Always prioritize clarity and maintainability—use descriptive variable names and document shared state dependencies. This approach improves test reusability, enhances readability, and supports more complex workflows in your automation suite.

👉 For more articles like this, visit my site: https://careersuccesso.com/

Top comments (1)

Collapse
 
sebastianclavijo profile image
Sebastian Clavijo Suero

Hi Sehani, interesting article.
For the example in the section 'Using Test-Specific Variables', since the variable is set in a test, and then reused in another test, this would make the tests not isolated, and that is a practice that is better to avoid. If the first test fail, the second will fail too, and even more if you .skip a test or alter the order in the file you might not have the variable set yet.
I use js variables for example for cases retrieving a token that I want to use in all (or most) of my tests, and I set the js variable in the before() hook. That way if the retrieval in the before fails, all tests are aborted.
Doing this way you ensure the principle of test isolation, since make the test independent of the order that is run, and the failure of one does not affect the others.

The issue with using an environment variable is that works if you set in a beforeEach(), but the value will not be maintained if you do in the before() hook (only the 1st test will know the value, and will be cleanup automatically by Cypress after the first test runs.

A 4th way that I find very useful for same cases is store the value/retrieve from a Node variable using cypress tasks. This is really useful when need to get something at the very beginning of a run of all the tests in your project.
A recent example recently is when I loaded bunch of resources at the beginning of a run that was going to be used by most of the test suites.

Just wanted to share my experience in case could be of help.
As I said, interesting article and useful.
Thanks!