CodeceptJS Database Helper
CodeceptJS Database Helper (codeceptjs-dbhelper) is a utility designed to integrate database interaction directly into CodeceptJS end-to-end and integration tests. It leverages the 'database-js' library and its various drivers, allowing testers to execute SQL queries or database commands to prepare and clean up test data efficiently. This helper is particularly useful for managing database state before and after test case execution, ensuring test isolation and consistent environments. The current stable version is 1.2.2, with releases typically tied to bug fixes or minor enhancements like improved JSDoc and TypeScript definitions (added in v1.1.0). A key differentiator is its compatibility across CodeceptJS versions 1, 2, and 3, and its reliance on the flexible 'database-js' ecosystem for connecting to a wide array of database types, including MySQL, PostgreSQL, SQLite, MS SQL Server, and even file-based sources like CSV and Excel. It simplifies database operations within the test runner's context without requiring direct database client imports in individual test files.
Common errors
-
Error: Cannot find module 'database-js-mysql'
cause A specific database driver for 'database-js' (e.g., 'database-js-mysql') was not installed, but its connection string was used.fixInstall the required database driver using npm: `npm i -D database-js-YOUR_DRIVER_NAME`. For example, `npm i -D database-js-mysql`. -
TypeError: I.connect is not a function
cause The `DbHelper` was not correctly configured in your `codecept.conf.js` file, or CodeceptJS failed to load it.fixVerify that `codeceptjs-dbhelper` is listed in the `helpers` section of your `codecept.conf.js` file with the correct `require` path, typically `"require": "codeceptjs-dbhelper"`. -
Error: SQLITE_CANTOPEN: unable to open database file
cause The specified path for a SQLite database file in the connection string is incorrect, or there are insufficient file system permissions to create/access the file.fixCheck the database file path in your connection string and ensure the test runner has read/write permissions to that directory. Use an absolute path if necessary for clarity.
Warnings
- gotcha The DbHelper relies on the `database-js` abstraction layer and specific database drivers. You must manually install `database-js` and the chosen driver (e.g., `database-js-mysql`, `database-js-sqlite`) separately from the helper itself.
- gotcha When upgrading CodeceptJS from version 2 to 3, the argument signature for `Scenario`, `Before`, and `After` callbacks changed. CodeceptJS 2 passes `I` directly (e.g., `async (I) => { ... }`), while CodeceptJS 3 requires `I` to be destructured from an object (e.g., `async ({ I }) => { ... }`).
- gotcha Ensure your database connection strings are correctly formatted and accessible from the environment where CodeceptJS tests are running. Common issues include incorrect host, port, username, password, or database name, as well as network/firewall restrictions.
Install
-
npm install codeceptjs-dbhelper -
yarn add codeceptjs-dbhelper -
pnpm add codeceptjs-dbhelper
Imports
- DbHelper Configuration
import { DbHelper } from 'codeceptjs-dbhelper';{ "helpers": { "DbHelper": { "require": "codeceptjs-dbhelper", "host": "localhost", "user": "root" } } } - I.connect
I.connect("mydb", "mysql://user:pass@host:port/dbname"); - I.run
await I.run("mydb", "SELECT * FROM users WHERE id = ?", userId);
Quickstart
const { BeforeSuite, AfterSuite, Before, Scenario } = require('codeceptjs');
BeforeSuite(async ({ I }) => {
// Establish a database connection named 'testdb'
// Replace connection string with your actual database details and credentials
I.connect("testdb", `mysql://root:password@localhost:3306/testdb`);
});
AfterSuite(async ({ I }) => {
// Close the database connection named 'testdb'
await I.removeConnection("testdb");
});
Before(async ({ I }) => {
// Clean up and seed the 'user' table before each test for a clean state
await I.run("testdb", "DELETE FROM user");
await I.run("testdb", "INSERT INTO user (username, password) VALUES (?, ?)", "admin", "123456");
await I.run("testdb", "INSERT INTO user (username, password) VALUES (?, ?)", "bob", "654321");
});
Scenario('should retrieve a specific user from the database', async ({ I }) => {
// Execute a query to retrieve users and perform assertions
const users = await I.run("testdb", "SELECT username FROM user WHERE username = ?", "admin");
console.log('Found users:', users);
I.assert(users.length).equals(1);
I.assert(users[0].username).equals('admin');
const nonExistentUser = await I.run("testdb", "SELECT username FROM user WHERE username = ?", "charlie");
I.assert(nonExistentUser.length).equals(0);
});