Ensuring Database Isolation in ESHOPMAN Integration Tests: A Deep Dive into Schema Configuration

For ESHOPMAN developers building robust headless commerce solutions, ensuring reliable and isolated testing environments is paramount. Integration tests, especially when dealing with database interactions, require precise control over the testing schema. Recently, our community identified a critical insight regarding ESHOPMAN's integration testing utilities, specifically how database schema configurations are handled.

The Challenge: Misleading Schema Configuration in ESHOPMAN Integration Tests

A key finding revealed that while ESHOPMAN's @eshopman/test-utils package (specifically, the eshopmanIntegrationTestRunner) accepts a schema option to define a custom PostgreSQL schema for test suites, this configuration was not consistently applied across the entire ESHOPMAN application context during testing. Developers expected their integration tests to run in an isolated, custom schema, but the underlying ESHOPMAN modules and application logic continued to interact with the default public schema.

This discrepancy led to several critical issues:

  • False Isolation: Test suites that specified a custom schema believed they were operating in isolation, but ESHOPMAN modules might still read from or write to the public schema, leading to unpredictable test outcomes and potential data contamination.
  • Misleading Diagnostics: The dbConfig.schema property within the test suite options would correctly report the requested custom schema, giving a false sense of security about the active database context.
  • Inconsistent Teardown: Database truncation and teardown helpers, which often respect the specified schema, could operate on a different schema than where the ESHOPMAN application actually wrote data, leaving orphaned test data or failing to clean up correctly.

Understanding the Technical Gap

The root cause was identified in how the ESHOPMAN configuration loader override functioned. While the eshopmanIntegrationTestRunner internally stored the requested schema, the mechanism responsible for overriding the ESHOPMAN project's runtime configuration (configLoaderOverride) did not propagate this schema option to the application's database settings. It primarily handled parameters like clientUrl and debug, but lacked a field to control the database schema for the running ESHOPMAN instance.

For example, the runner would correctly capture the schema:

this.schema = config.schema ?? "public"
this.dbC> dbName: this.dbName,
clientUrl: getDatabaseURL(this.dbName),
schema: this.schema,
debug: this.debug,
}

However, the configuration override function only processed a limited set of database parameters, omitting the schema:

override: {
clientUrl: string
debug?: boolean
}

This meant that while low-level database helpers might correctly use the custom schema, the ESHOPMAN application's modules, which rely on the global configuration, would default to public.

Proposed Solution and Best Practices

To address this, the ESHOPMAN community suggests the following enhancements and best practices for developers:

  1. Extend Configuration Override: The configLoaderOverride function should be updated to accept and apply the schema option directly to the ESHOPMAN project's database configuration, ensuring the running application uses the intended schema.
  2. Schema Creation Pre-Migration: Before running migrations within an integration test path, ensure the custom schema exists (e.g., CREATE SCHEMA IF NOT EXISTS ...). This prevents migration failures in new, isolated test schemas.
  3. Regression Testing: Implement dedicated regression tests that create entities through ESHOPMAN's Admin API or Store API into a non-public schema and then assert that data persistence and teardown operations correctly target that specific schema.

A reproduction sketch for such a test might look like this:

eshopmanIntegrationTestRunner({
schema: "tests",
testSuite: ({ getContainer, dbConfig }) => {
it("reports the custom schema", () => {
expect(dbConfig.schema).toBe("tests")
})

it("should persist module data in the custom schema", async () => {
// Create an entity through an ESHOPMAN module.
// Query information_schema / pg_tables and observe it landed in "tests",
// not "public".
})
},
})

Conclusion

This community insight underscores the importance of precise database configuration in ESHOPMAN integration testing. By ensuring that custom schemas are fully honored from the test runner through to the core ESHOPMAN application, developers can achieve true test isolation, leading to more reliable, maintainable, and robust headless commerce solutions built on ESHOPMAN and deployed via HubSpot CMS.

Start with the tools

Explore migration tools

See options, compare methods, and pick the path that fits your store.

Explore migration tools