Oninit® ifxTAP — How It Works
ifxTAP keeps test logic inside Informix and handles execution and reporting through a lightweight Java runner. You write tests in SQL and SPL. The assertion routines evaluate the results and record each outcome; the runner manages the transaction, collects those outcomes and produces TAP output.
Architecture
ifxTAP has two main components:
- An SPL assertion library installed in your test database. Its
tap_*routines (see the Assertion Reference) check values, inspect database objects and record test results. - A Java command-line runner,
ifxtap, that connects through JDBC, executes.sqltest files and reports their results.
The assertions run in Informix, alongside the procedures, functions, triggers and data they test. The runner handles connection management, execution order, transaction boundaries and reporting.
The execution cycle
For each test file, the runner:
- Prepares the session’s results table and test state.
- Starts a transaction with
BEGIN WORK. - Executes the file’s fixture setup, database operations and assertions.
- Collects the recorded assertion results and checks the test count against the plan.
- Issues
ROLLBACK WORKto undo transactional changes. - Prints the results in TAP format.
Each file therefore forms a separate test unit with its own transaction. Files should create the fixtures they need rather than depend on changes made by an earlier file.
Isolation by rollback
In a logged Informix database, supported DDL operations participate in transactions. A test can create fixtures, insert or update data, and create transactional database objects within the runner’s transaction.
At the end of the file, ROLLBACK WORK removes those changes. Tables, indexes and routines created through
supported transactional DDL disappear, and changes to logged data are undone.
This makes tests repeatable without requiring a cleanup statement for every transactional change. The runner owns the
transaction boundary, so test files must leave transaction control to the runner: it refuses a COMMIT,
ROLLBACK or BEGIN WORK statement in a test file without running it, and fails a file in which
a routine ended the transaction.
Recording assertion results
Each assertion writes a row to a session-local temporary results table. A result records:
| Field | Purpose |
|---|---|
| Test number | Identifies the assertion within the test file |
| Pass flag | Records whether the assertion succeeded |
| Description | Names the behaviour or condition being checked |
| Diagnostics | Provides details that help explain a failure |
The table is created using CREATE TEMP TABLE ... WITH NO LOG. Writes to it are not rolled back with the
test’s logged changes, allowing assertion results to remain available when the test transaction is undone.
The runner collects the results before issuing the rollback. Because rollback does not clear the unlogged result rows, the runner must reset the results table and test state between files.
The table belongs to the connection’s session, keeping its results separate from those produced by other test sessions.
TAP output and failure reporting
The runner converts recorded results into TAP version 13 output:
1..3
ok 1 - customer table exists
ok 2 - inserting an order updates the balance
not ok 3 - duplicate customer is rejected
---
message: no error raised; wanted -268
...
The plan, 1..3, declares that three assertions are expected. Each ok or not ok line
reports an assertion outcome. For a failure, the details appear in the indented block beneath it. Lines beginning with
# carry other messages, such as the name of each test section and anything written with tap_diag.
The runner returns a non-zero exit code when:
- An assertion fails.
- The number of completed assertions differs from the test plan.
- A test run does not complete.
This allows a CI pipeline to detect failure from the exit code. The TAP output carries the detail, and a run of several files is one TAP stream; see Runner and TAP Output.
Routine naming and installation
Informix identifies database objects by owner rather than using schemas. ifxTAP uses the
tap_ prefix to distinguish its routines from application routines.
Before creating its objects, the installer checks for existing tap_* objects that could conflict with the
library. Reserve that prefix for ifxTAP, and use owner-qualified names where needed to make object resolution explicit.
Changes rollback cannot undo
Rollback provides isolation for transactional changes. Some operations need separate handling:
| Operation | Cleanup consideration |
|---|---|
| Sequence allocation | Allocated values are not restored by rollback |
| Writes to RAW or other non-logged tables | Data changes may remain after the transaction is rolled back |
| Routines that commit work | Committed changes are outside the runner’s final rollback. The runner detects this and fails the file, but cannot undo the commit |
SYSTEM calls or file I/O | External effects are outside database transaction control |
Use explicit teardown hooks for these cases. Where an effect cannot be reliably reversed, use disposable test resources and design assertions around the documented behaviour—for example, do not assume sequence values will be consecutive across repeated test runs.
Requirements
- Informix 14.10 or later with a logged test database.
- Java 11 or later on the machine running
ifxtap. - The IBM Informix JDBC driver, supplied separately.
- Permissions to execute the assertion library and perform the operations required by the tests.