Cypress Database Testing (with Best Practices)

On This Page Can Cypress be employ for Database Testing?March 22, 2026 · 20 min read · Tool Comparison

Cypress Database Testing (with Best Practices)

is an end-to-end testing framework that is primarily used for prove web applications. However, it is also potential to use Cypress for database testing. Database examination is an crucial aspect of as it ensures that the datum store in the database is precise and consistent.

Overview

Key Benefits of Using Cypress for Database Testing

  • End-to-End Validation: Confirms data accuracy between the UI and database.
  • Other Bug Detection: Identifies schema mistake, query failure, and mismatches before production.
  • Improved Test Reliability: Automates cheque for data consistency and performance.
  • Seamless Integration: Works with CI/CD pipelines to enable uninterrupted calibre validation.

How to Perform Database Testing with Cypress

  1. Set Up a Test Database– Create a safe, isolated environment for essay.
  2. Establish Database Connection– Configure plugins or Node.js library for secure connectivity.
  3. Write Queries and Tests– Validate CRUD operations, schema rules, and data constraints.
  4. Run Tests in Cypress– Execute automate database tests alongside UI trial.

Business Impact of Cypress Database Testing

  • Faster liberation cycles with fewer production issues.
  • Improved production calibre through end-to-end substantiation.
  • Lower care costs by automating manual database checks.
  • Stronger confidence for development and QA teams to ship at scale.

This guide explicate Cypress Database Testing and its best practices in point.

Can Cypress be used for Database Testing?

  • Yes. Using Cypress for database testing can provide developers with fast and authentic tests for their database operations.
  • In this process, developers can set up a test database, connect to the database, write tests to interact with the database and run the tests utilise the.
  • With Cypress database examination, developers can ensure that their application and database perform well under and that their data is precise and consistent.

Setting up Cypress for Database Testing

Installing Cypress

To install Cypress for database testing, postdate these steps:

Step 1: Install themysqlplugin. Once it is installed, it should ruminate under yourpackage.json.

Step 2: To connect to a database, we will ask the following connector information for the DB. We will add this information towards the end in the cypress.json file inside the & # 8220; env & # 8221; object.

`` env '': {'' DB '': {'' user '': `` myuser '', '' host '': `` 127.0.0.1 '', '' database '': `` testDB '', '' password '': `` passing '', '' port '': 32763}}

Start by adding a new Cypress Task telephone & # 8220; DATABASE & # 8221;. For this, we will add a new task in the cypress/plugins/index.js file. This task accepts two main things:

  • dbConfig& # 8211; (this the DB connection info retrieved from cypress.json file using Cypress.env ()
  • sql & # 8211; (this is the SQL command which we need to fulfill)

Setting up a Test Database

To set up a test database using Cypress, you can follow these general steps:

1. Install a local MySQL host: To create a tryout database, you need to install a local MySQL host on your machine. You can download MySQL from the official site.

2. Create a new database: Once you have install MySQL, you can create a new database that will be utilise for quiz. You can do this using the MySQL command line interface or GUI.

For instance, to create a new database called & # 8220; testdb & # 8221;, you can run the following command in the MySQL bid line interface:

CREATE DATABASE testdb;

3. Configure your application: You need to configure your coating to use the test database instead of the product database. You can do this in the application codification or through environment variables.

For example, you can set the DATABASE_URL environment variable to the connection twine for the tryout database:

export DATABASE_URL=mysql: //testuser: testpass @ localhost/testdb

4. Connect to the test database: In your, you need to connect to the test database using the mysql2 software. Depending on your needs, you can create a connection pool or a individual connection.

For example, you can create a connection pool in a db.js file:

const mysql = require ('mysql2/promise '); const pool = mysql.createPool (process.env.DATABASE_URL); module.exports = pool;

5. Write your tests: Once connected to the trial database, you can write your exam. Your test can include tuck datum into the database, updating subsist data, deleting data, or running queries to retrieve datum from the database.

For example, you can indite a test that insert a new user into the database

const pool = require ('./db '); describe ('User management ', () = & gt; {it ('should tuck a new user ', async () = & gt; {const result = await pool.execute ('INSERT INTO users (name, e-mail) VALUES (?,?) ', ['John Doe ', 'johndoe @ example.com ']); expect (result [0] .affectedRows) .to.equal (1);});});

6. Clean up the test database:After running your test, you need to clean up the test database to ensure that the database is in a consistent province for the succeeding test run. You can do this by deleting all the test data or by restoring the database to its original state.

For example, you can pen a test that deletes all the exploiter from the database after each test

const pond = require ('./db '); describe ('User management ', () = & gt; {beforeEach (async () = & gt; {await pool.execute ('DELETE FROM users ');}); it ('should insert a new user ', async () = & gt; {const result = await pool.execute ('INSERT INTO exploiter (gens, e-mail) VALUES (?,?) ', ['John Doe ', 'johndoe @ example.com ']); look (result [0] .affectedRows) .to.equal (1);});});

By postdate these steps, you can set up a examination database expend Cypress for your Node.js application and write tests to ensure that your coating and database function aright. It is important to note that you should always use a separate test database when lead tryout and ne'er use the production database.

NOTE:BrowserStack MYSQL2 connections are only possible if the DB host is publicly approachable or if a lightweight waiter constituent of the is initiated on the same pole on which BrowserStack runs the Cypress test.

Connecting Cypress to the Test Database

To link Cypress to a tryout database, you can use a database driver to launch a connection and execute enquiry against the database.

1. Install the mysql2 package:You need to install the mysql2 bundle as a dev dependency in your Cypress project. You can do this by run the following command in your terminal:

npm install -- save-dev mysql2

2. Create a connectedness pond: You can make a connection pool in a db.js file that exports a pond object. The pond object will be used to manage connections to the database.

const mysql = require ('mysql2/promise '); const pool = mysql.createPool ({host: 'localhost ', exploiter: 'testuser ', password: 'testpass ', database: 'testdb ', connectionLimit: 10 // maximal number of connexion in the pond}); module.exports = pool;

The above codification create a connection pond with a maximum of 10 connections to the test database.

3. Use the connective pond in your test: In your Cypress tests, you can import the db.js file and use the connective pool to execute query against the database. For example, you can write a test that inserts a new exploiter into the exploiter table:

const pond = require ('./db '); describe ('User management ', () = & gt; {it ('should insert a new user ', async () = & gt; {const upshot = await pool.execute ('INSERT INTO user (name, e-mail) VALUES (?,?) ', ['John Doe ', 'johndoe @ example.com ']); wait (result [0] .affectedRows) .to.equal (1);});});

The above codification executes an INSERT inquiry to introduce a new exploiter with the name & # 8220; John Doe & # 8221; and email & # 8220; johndoe @ example.com & # 8221; into the user & # 8217; s table.

For autonomous testing across multiple user personas, check out SUSATest — it explores your app like 10 different real users.

By postdate these steps, you can connect Cypress to a test database and use it to pen tests that verify the behavior of your application touch the database. Note that the exact steps may vary depending on the database you are using and the database driver you use to connect to it.

Writing Database Tests with Cypress

Writing Test Cases for CRUD operations

When testing CRUD (Create, Read, Update, Delete) operations for database testing in Cypress, it is important to see the database schema and operation to be performed clearly.

The test cases should cover all the potential scenarios and edge cases to ensure the system & # 8217; s proper performance.

Test cases for CRUD Operations:

  • Create a user record: This exam event verifies that the CREATE operation act as expected. Using the INSERT INTO SQL argument, we introduce a new disk into the & # 8220; users & # 8221; table. We so say the record using the SELECT statement and control that the record was create successfully.
describe ('Create ', () = & gt; {it ('should add a new record to the `` users '' table ', () = & gt; {const newRecord = {name: 'Alice ', email: 'alice @ example.com '} cy.task ('insertRecord ', {table: 'users ', record: newRecord}) .then (() = & gt; {cy.task ('queryDatabase ', 'SELECT * FROM users WHERE e-mail = `` alice @ example.com '' ') .then ((result) = & gt; {expect (consequence) .to.have.lengthOf (1) expect (ensue [0]) .to.deep.include ({id: 4, name: 'Alice ', email: 'alice @ example.com '})})})})})

In this trial case, we use the cy.task () command to call the insertRecord task with the table name and the new record to be tuck. We so use the then () method to handle the result of the query and use another cy.task () command to get the newly infix record from the & # 8220; users & # 8221; table. We so use the expect () averment to verify that the result hold the wait information, including the newly inserted record.

  • Read a user disk: This tryout cause verifies that the READ operation work as expected. We insert a new record into the & # 8220; users & # 8221; table and then read the like record using the SELECT argument. We verify that the disc was read successfully by assure that the values of the columns mate the expected values.
describe ('Read ', () = & gt; {it ('should retrieve all records from the `` users '' table ', () = & gt; {cy.task ('queryDatabase ', 'SELECT * FROM users ') .then ((result) = & gt; {expect (result) .to.have.lengthOf (4) expect (ensue [0]) .to.deep.include ({id: 1, name: 'John Doe ', email: 'johndoe @ example.com '}) expect (result [1]) .to.deep.include ({id: 2, gens: 'Jane Doe ', e-mail: 'janedoe @ example.com '}) expect (ensue [2]) .to.deep.include ({id: 3, gens: 'Bob Smith ', email: 'bobsmith @ example.com '}) expect (result [3]) .to.deep.include ({id: 4, name: 'Alice ', e-mail: 'alice @ example.com '})})})})

In this test case, we use the cy.task () command to call the queryDatabase undertaking with the SQL query to fetch all disc from the & # 8220; users & # 8221; table. We then use the then () method to handle the question & # 8217; s upshot and use the expect () assertion to verify that the result contains the expected data.

  • Update a user record: This test case verifies that the UPDATE operation act as expected. We inclose a new record into the & # 8220; users & # 8221; table and then update the record using the UPDATE SQL argument.

We control that the record was updated successfully by checking that the updated value of the column matches the expected value.

describe ('Update ', () = & gt; {it ('should update the email of the user with ID 1 ', () = & gt; {const updates = {email: 'johndoe_updated @ example.com '} cy.task ('updateRecord ', {table: 'users ', id: 1, updates}) .then (() = & gt; {cy.task ('queryDatabase ', 'SELECT * FROM users WHERE id = 1 ') .then ((consequence) = & gt; {look (result) .to.have.lengthOf (1) expect (result [0]) .to.deep.include ({id: 1, gens: 'John Doe ', e-mail: 'johndoe_updated @ example.com '})})})})})

In this test case, specify the update to the record with ID 1. Then use the cy.task () command to call the updateRecord labor with the table gens, the record ID to be updated, and the updates to be made.

Use the then () method to handle the result of the query and use another cy.task () command to fetch the updated record from the & # 8220; users & # 8221; table. Use the expect () assertion to control that the upshot contains the expected data, include the updated e-mail address.

  • Delete a exploiter record: This test event verifies that the DELETE operation act as expected. We insert a new record into the & # 8220; user & # 8221; table and then delete the platter using the DELETE SQL argument. We verify that the record was deleted successfully by check that the platter is no longer present in the table.
describe ('Delete ', () = & gt; {it ('should erase the user with ID 2 ', () = & gt; {cy.task ('deleteRecord ', {table: 'users ', id: 2}) .then (() = & gt; {cy.task ('queryDatabase ', 'SELECT * FROM users ') .then ((event) = & gt; {expect (event) .to.have.lengthOf (3) expect (result) .to.not.deep.include ({id: 2, gens: 'Jane Doe ', e-mail: 'janedoe @ example.com '})})})})})

In this test case, we use the cy.task () command to call the deleteRecord chore with the table gens and the ID of the record to be cancel. We use the then () method to deal the solution of the query and use another cy.task () bid to fetch all records from the & # 8220; users & # 8221; table. In each test case, we use the cy.task () command to call the like SQL statement to perform the database operation.

Use the cy.task () command again to say the information from the database and verify that the operation was successful.It is crucial to note that the cy.task () command is asynchronous, so we need to use the so () method to handle the result of the database operation.

Verifying Data Integrity

To verify the data wholeness of the database in Cypress, you can use SQL queries to check if the information in the database match the expected values.

Here & # 8217; s how you can do it:

  • Create a test suit to verify data integrity:
describe ('Verifying data unity of the database ', () = & gt; {it ('should have the expected data in the database ', () = & gt; {// use cy.task () command to ring the SQL enquiry cy.task ('queryDatabase ', 'SELECT * FROM user ') .then ((result) = & gt; {// verify that the data in the database matches the await data expect (result) .to.deep.equal ([{id: 1, name: 'John Doe ', email: 'johndoe @ example.com '}, {id: 2, name: 'Jane Doe ', email: 'janedoe @ example.com '}, {id: 3, gens: 'Bob Smith ', email: 'bobsmith @ example.com '}, // add more expected information as required])})})})

In this test case, we use the cy.task () command to call the SQL query to fetch all the records from the & # 8220; users & # 8221; table. We then use the then () method to handle the interrogation & # 8217; s result and liken it with the expected data using the expect () averment.

  • Implement the queryDatabase project in the plugins file:
const {Pool} = require ('pg ') module.exports = (on, config) = & gt; {// configure the database link const pool = new Pool ({host: 'localhost ', user: 'postgres ', watchword: 'password ', database: 'mydatabase'}) // define the queryDatabase task on ('task ', {queryDatabase: (query) = & gt; {return pool.query (query) .then ((result) = & gt; {return result.rows})}})}

In this code, we configure the PostgreSQL database connection using the pg module and define the queryDatabase task that takes a SQL query as a parameter and returns the result of the query as an array of objects.

Note: You must install the pg module habituate npm to use it in your code.

By running this test case, you can check that the datum in the database matches the expected data and that there is no data corruption or inconsistency.

Testing Database Transactions

Transactions furnish a way to group a set of database operations into a single unit of employment that either succeeds or fail as a whole. Testing database transactions is an crucial aspect of testing web applications, ensuring the application can handle database operations aright and consistently.

It involves examine that the proceedings are fulfil right and provide the expected results regarding the database state. To test database transaction, we can use Cypress to execute database queries and transactions.

  • Assuming you & # 8217; re using a Node.js backend and a database that supports transactions (e.g. PostgreSQL), you can use the cy.task command in Cypress to accomplish database queries and dealings.
  • First, you & # 8217; ll want to create a database connection in your Node.js backend that Cypress can use.

Here & # 8217; s an model of how to do this using the pg library

const {Pool} = require ('pg '); const pond = new Pool ({user: 'your-db-user ', host: 'your-db-host ', database: 'your-db-name ', word: 'your-db-password ', port: 5432, // or your database port}); module.exports = pool;
  • Next, you can create a Cypress command that fulfil a database transaction apply the connection created above.
  • This command should get a transaction, accomplish a callback function that can bear any database inquiry or dealings, and either commit or roller back the transaction establish on the success of the recall role
const pool = require (' .. /path/to/your/database/connection '); Cypress.Commands.add ('runTransaction ', async (transactionCallback) = & gt; {const guest = await pool.connect (); try {await client.query ('BEGIN '); wait transactionCallback (client); await client.query ('COMMIT ');} match (mistake) {await client.query ('ROLLBACK '); throw mistake;} finally {client.release ();}});

This command starts a database dealings, executes a callback part that can curb any database inquiry or transactions, and either commits or rolls back the transaction based on the success of the callback function.

Here & # 8217; s an example trial that uses the runTransaction command:

describe ('Database Transactions ', () = & gt; {it ('should execute a database transaction ', () = & gt; {cy.runTransaction (async (customer) = & gt; {// Insert a new user into the database await client.query ('INSERT INTO users (name, email) VALUES ($ 1, $ 2) ', ['John Doe ', 'john.doe @ example.com ']); // Query the database to check if the user was inserted const {rows} = await client.query ('SELECT * FROM exploiter WHERE name = $ 1 ', ['John Doe ']); expect (rows.length) .to.equal (1);});});});

In this example, we & # 8217; re inserting a new user into the database within the transaction and so question the database to check if the user was inserted successfully. If the recall role complete successfully, the dealing will be committed and the test will surpass.

Testing Database Migrations

Database Migrations provide a way to incrementally update the database schema, and ensure that the database schema is consistent across different surround (e.g. growing, staging, production).

To quiz database migrations, we typically need to do the following

Create a migration script that Cypress can execute. Assuming you & # 8217; re using a Node.js backend and a database that supports migrations (e.g. PostgreSQL with the knex library), you can use the cy.task command in Cypress to execute migration scripts.

First, you & # 8217; ll need to create a migration script that Cypress can execute.

Talk to an Expert

Here & # 8217; s an representative of how to make a migration using knex:

exports.up = function (knex) {return knex.schema.createTable ('users ', function (table) {table.increments ('id '); table.string ('name '); table.string ('email ') .unique (); table.timestamps (true, true);});}; exports.down = function (knex) {return knex.schema.dropTable ('users ');};

This migration playscript creates a new user table with an id, name, e-mail, and created_at and updated_at timestamps.

1. Create a Cypress command that executes the migration hand using a database connector. make a Cypress command that execute migration scripts use knex: This command starts a knex database connection, lam the latest migrations, and either commits or rolls back the transaction base on the success of the migration script.

const knex = require ('knex '); const config = require (' .. /path/to/your/knexfile '); Cypress.Commands.add ('runMigrations ', async () = & gt; {const db = knex (config); try {wait db.migrate.latest ();} catch (err) {console.error (err); await db.rollback ();} lastly {await db.destroy ();}});

2. Write tests that use the Cypress command to action migration book and make assertions about the expected database schema modification.

Test that uses the runMigrations command:

describe ('Database Migrations ', () = & gt; {it ('should run database migration ', () = & gt; {cy.runMigrations (); // Assert that the users table was make cy.task ('knex ', {sql: 'SELECT * FROM users '}) .then ((effect) = & gt; {ask (result.rows.length) .to.equal (0);});}); it ('should roll back failed migrations ', () = & gt; {// Create a migration script that fails const migration = ` CREATE TABLE users (id INTEGER PRIMARY KEY); INSERT INTO users (id) VALUES (1); INSERT INTO users (id) VALUES (1); `; // Execute the migration script cy.task ('knex ', {sql: migration}) .should ('throw ') .runMigrations (); // Assert that the exploiter table was not created cy.task ('knex ', {sql: 'SELECT * FROM user '}) .then ((issue) = & gt; {expect (result.rows.length) .to.equal (0);});});});

In this instance, we feature two tests: one that tests successful migrations and one that examine failed migrations. The maiden test go the runMigrations command and verifies that the user table was make.

The second test executes a migration script that designedly fails, and verifies that the migration is rolled back and that the user table was not created. When prove database migrations, it & # 8217; s significant to test both successful and failed migrations. Successful migrations should update the database schema correctly, while failed migration should wheel back any changes do to the database schema.

Four Best Practices for Cypress DB Testing

1. Keeping the Test Data separate from Production Data

Keeping the test data separate from the production information in Cypress tests is essential. If your trial are writing or modifying information in your product database, it can lead to inconsistencies, corruption, or even loss.To proceed trial data separate from production datum, here are some best practices:

  • Use a separate test database:Use a separate database for your tests to keep your product information safe. This ensures that the datum used in your examination will not affect your product datum. You can too use the same database server but a different name for testing purposes.
  • Use database migration scripts:Use database migration scripts to set up the tryout database outline and seed the initial data. This secure that your test data is constantly in a known state and consistent across test runs.
  • Use test-specific seed data:Use seed data specific to the tryout being run to ensure that the test is isolated and reproducible. This also makes it easier to trouble-shoot issues that may arise during testing.
  • Use transactional examination:Use transactional testing to ensure that each exam runs in a database transaction and rollback the transaction after the test completes. This secure that your test data remains separate from your production data and that your production datum is unaffected by your tests.
  • Clean up exam datum:After running tests, clean up any test data created in the trial database. This can be done using database migration playscript or cleanup functions in your test.

2. Testing with Realistic Data

Testing with realistic data in Cypress can help you catch bugs and issues that may not appear with man-made test data.

  • Use real-world scenarios:Develop test instance that simulate real-world scenarios. For example, test scenarios include multiple users, different user roles, or different data sets that your customers commonly use.
  • Use production-like data:Use production-like data for examine to ensure your tests are as naturalistic as potential. This entail using datum representative of what your client use in production, include data volume, information types, and data distribution.
  • Use anonymized data:Anonymize data for test to protect sensitive customer information. This ensures that your tests do not curb any identifiable data that could be employ to break your customer & # 8217; privacy.
  • Use trial data generators:Use test data generators to automate the creation of realistic data. This facilitate you generate large amounts of realistic data promptly, which is especially utile when testing with large datasets.
  • Use randomization:Use randomisation techniques to give examination data that covers a wide range of values and edge cases. This assist you uncover potential bugs or issues that may not appear with a small subset of information.
  • Use visualisations:Use data visualization techniques to make it easier to understand and analyze trial results. This can help you place patterns or trends that may point issues or areas for improvement.

3. Minimising test data duplication

Minimizing test information duplication in Cypress can help you avoid unnecessary maintenance and improve the legibility and reliability of your examination.

  • Use secureness:Use fixtures to load test data into your tests. Fixtures are external data files that contain test datum in a format that Cypress can use, which helps you avoid duplicating test datum within your test files and allows you to reuse data across multiple test.
  • Use data factories:Use datum factories to generate test data dynamically. Data manufactory can help you create test data that is unique to each test, which reduces the demand for duplication data.
  • Use database migration:Use database migrations to seed the test database with initial data. This can help you avoid duplicating test data in your test file and allows you to negociate your test data separately from your test codification.
  • Use test-specific information:Use test-specific data to keep your tests independent and avoid duplicating data across multiple tests. Each test should have its unique information set specific to the test being executed.
  • Use shared information:Use shared data when it do sense. Shared datum can be used across multiple trial to amend readability and maintainability. However, be careful not to overuse shared data, as it can make it difficult to understand the dependencies between tests.

4. Using Cypress Plugins for database testing

Cypress pluginsare a powerful feature that allows you to extend the functionality of Cypress with usage code. Regarding Cypress database testing, plugins can be used to simplify and automate the testing process.

  • Database plugins:Cypress indorse plugins that interact with database. These plugins can aid you simplify database interactions, such as creating, reading, updating, and deleting data. For example, you can use the cypress-firebase plugin to interact with a Firebase database or the cypress-mongo-seed plugin to seed a MongoDB database.
  • Test data coevals plugins:Plugins can too generate trial data automatically. These plugins can facilitate you make large sets of realistic data quickly, which is especially useful when testing with large datasets. For example, you can use the cypress-faker plugin to return naturalistic examination information or the cypress-data-session plugin to generate unique test data for each trial run.
  • Cypress tasks:Cypress labor are another way to use plugins for database testing. Tasks allow you to accomplish custom Node.js codification during your Cypress test, which can be used to interact with databases or perform other operations. For example, you can use a chore to run a database migration playscript before your tests or to seed your exam database with initial data.
  • Assertion plugins:Assertion plugins can add custom assertions to your tests. These plugins can help you formalise data retrieved from the database and guarantee it meet certain criteria. For example, you can use the chai-firebase plugin to add Firebase-specific assertions to your tests.
Tags
26,000+ Views

# Ask-and-Contributeabout this topic with our Discord community.

Related Guides

Automate This With SUSA

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.

Try SUSA Free

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free