Overview I'm excited to announce the release of testcontainers-iris-node
, a Node.js library that makes it easy to spin up temporary InterSystems IRIS containers for integration and E2E testing. This project is a natural addition to the existing family of Testcontainers adapters for IRIS, including testcontainers-iris-python and testcontainers-iris-java.
Why testcontainers-iris-node? As a Node.js developer working with InterSystems IRIS, I often faced challenges when setting up test environments that mimic production. testcontainers-iris-node
solves this by leveraging the testcontainers-node
framework to create isolated IRIS environments on-demand.
This is particularly valuable for:
- Integration testing with IRIS databases
- Testing data pipelines or microservices
- Automating test environments in CI pipelines
Features
- Launches IRIS in Docker containers using Testcontainers
- Supports custom Docker images and configuration
- Wait strategies to ensure IRIS is ready before tests begin
- Clean teardown between test runs
Getting Started
npm install testcontainers-iris --save-dev
Example Usage
import { IRISContainer } from "testcontainers-iris";
import { createConnection } from "@intersystems/intersystems-iris-native";
const IMAGE = "containers.intersystems.com/intersystems/iris-community:latest-preview";
const container = await new IRISContainer(IMAGE).start();
const connection = createConnection(container.getConnectionOptions());
const iris = connection.createIris();
const version = iris.classMethodString("%SYSTEM.Version", "GetNumber");
How It Works Internally, the library extends GenericContainer
from testcontainers
, adds IRIS-specific wait strategies, and provides helper methods for connection string generation and configuration overrides.
Supported Scenarios
- Jest or Mocha-based test suites
- CI environments (GitHub Actions, GitLab CI, Jenkins, etc.)
- Local development and debugging
Mocha Test Example You can also use this library for robust integration tests with Mocha. Here is an example setup:
test-setup.ts
import "source-map-support/register"
import "reflect-metadata"
import { IRISContainer, StartedIRISContainer } from "testcontainers-iris"
import { IRISNative } from "../../src"
import chai from "chai"
import sinonChai from "sinon-chai"
import chaiAsPromised from "chai-as-promised"
declare global {
var container: StartedIRISContainer | undefined
var connectionOptions: {
host: string
port: number
user: string
pwd: string
ns: string
}
}
process.env.TZ = "UTC"
chai.should()
chai.use(sinonChai)
chai.use(chaiAsPromised)
before(async () => {
console.log("Setting up test environment...")
const image = process.env["IRIS_IMAGE"]
let connectionOptions = {
host: "localhost",
port: 1972,
user: "_SYSTEM",
pwd: "SYS",
ns: "USER",
}
if (image) {
const container: StartedIRISContainer = await new IRISContainer(image)
.withNamespace("TEST")
.start()
console.log(`IRIS container started at ${container.getConnectionUri()}`)
global.container = container
connectionOptions = {
host: container.getHost(),
port: container.getMappedPort(1972),
user: container.getUsername(),
pwd: container.getPassword(),
ns: container.getNamespace(),
}
}
global.connectionOptions = connectionOptions
IRISNative.createConnection({ ...connectionOptions, sharedmemory: false })
})
after(async () => {
console.log("Cleaning up test environment...")
if (global.container) {
await global.container.stop()
}
delete global.container
})
Test case:
import { IRISNative, IRISConnection } from "../src/IRISNative"
describe("IRISNative test", () => {
let connection: IRISConnection
before(() => {
const connectionOptions = global.connectionOptions
connection = IRISNative.createConnection({ ...connectionOptions })
})
after(() => {
if (connection) {
connection.close()
}
})
it("should work", async () => {
const res = await connection.query(
"SELECT 1 AS test1, '2' AS test2",
[],
)
res.rows.should.be.an("array")
res.rows.should.have.lengthOf(1)
res.rows[0].should.be.an("object")
res.rows[0].should.have.property("test1")
res.rows[0].should.have.property("test2")
res.rows[0].should.have.property("test1", 1)
res.rows[0].should.have.property("test2", "2")
})
})
Used in typeorm-iris This library is also used in my typeorm-iris
project, which provides experimental TypeORM support for InterSystems IRIS. testcontainers-iris-node
powers the integration testing setup for that project, helping validate the ORM functionality against real IRIS instances.
Library Adoption Challenge As a library adoption developer, one of my biggest challenges is testing across multiple versions of InterSystems IRIS. This tool significantly simplifies that process by allowing easy switching and automation of containerized environments with different IRIS versions.
Comparison with Other Language Bindings While testcontainers-iris-python
and testcontainers-iris-java
are mature and support advanced features like bind mounts and custom startup scripts, the Node.js variant is streamlined for JavaScript/TypeScript environments and aims for simplicity and developer ergonomics.
Contribute and Feedback I welcome feedback, issues, and pull requests via GitHub: testcontainers-iris-node.
Closing Thoughts testcontainers-iris-node
lowers the barrier for robust, automated testing of IRIS-based applications in the Node.js ecosystem. Whether you're building APIs, ETL jobs, or integration services, this tool helps ensure confidence in your IRIS workflows.