API
The framework is built from plain, instantiable classes with instance methods - no static utilities. This page is the reference for the main entry points.
Hop fixtures (hop-junit-core)
@HopPipeline / @HopWorkflow
Method annotations that declare which artifact to run. Both are method-level only and not repeatable - declare one pipeline/workflow per test method. The single-level meta-annotation alias for @HopParameters is supported by @HopParameters, not by the pipeline/workflow annotations.
| Attribute | Description |
|---|---|
|
|
The artifact path, resolved against |
|
|
The Hop project home; defaults to |
|
|
The Hop run configuration used to build the engine; defaults to the local engine. |
|
|
Per-test |
The extension injects a HopPipelineFixture / HopWorkflowFixture:
@Test
@HopPipeline(value = "load/T_LOAD.hpl", projectHome = "src/test/resources")
void loads(final HopPipelineFixture pipeline) {
pipeline.with("load.table", "ORDERS")
.withConnection("SRC_ORACLE", src)
.execute()
.assertSuccess()
.assertLogContains("Partition created");
}
Parameters: @HopParameters / @HopParameter
Merged in ascending precedence: class-level batch (unless the method-level occurrence opts out with inherit = false), then method-level batch, then the parameters declared on the pipeline/workflow annotation. A single-level alias works by putting @HopParameters on another annotation.
Assertions: HopPipelineExecution / HopWorkflowExecution
execute() returns a fluent execution object:
-
assertSuccess()/assertFailure()- HopResulterror count assertions, with the Hop log appended to the failure message; -
assertLogContains(String)- substring assertion on the Hop log text; -
logText()/result()- direct access; -
assertThat(Consumer)- group custom assertions.
Database facade (hop-junit-database-core)
@Database
Repeatable method annotation declaring a named database; the same test body runs on both backends. Attributes: name(), init() (@DbInit[]), expected() (@DbExpected[]). The backend is resolved from database.default.implementation (default H2) through java.util.ServiceLoader; the database.default.h2.mode property (default ORACLE_EXTENDED) selects the H2 compatibility mode.
@DbInit / @DbExpected
@DbInit seeds the database: *.sql resources run as raw statements (schemas/DDL), anything else is loaded as a DBUnit dataset and applied with operation() (CLEAN_INSERT by default). Optional knobs: format() (AUTO infers from the extension), supportedDatabases() (empty = all), admin() (run through the admin connection - Oracle provisioning), caseSensitive().
The default AUTO resolution maps the resource extension to a dataset format: .yaml/.yml to YAML, .xml to flat XML (or full XML for the FLAT_XML/FULL_XML formats), .csv to CSV, .json to JSON. .xls/.xlsx map to XLS, which is available only when Apache POI is on the test classpath:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<scope>test</scope>
</dependency>
The version is managed by the hop-junit parent POM, so no <version> is needed. Without POI, seeding an .xls/.xlsx dataset fails with a clear message telling you to add those dependencies. YAML, XML, CSV and JSON need no extra dependency (DBUnit brings them transitively).
@DbExpected verifies a post-condition dataset in afterEach, only when the test passed. Knobs: format(), comparison() (STRICT/ORDERED/ROWCOUNT), ignoreColumn() (table.column or bare column), ignoreTable(), caseSensitive(). It supports the same formats as @DbInit.
JdbcConnectionSpec / @JdbcNamed
A named database is injected as a JdbcConnectionSpec:
void test(@JdbcNamed("SRC") final JdbcConnectionSpec src) {
// H2: jdbcUrl() is the plain in-memory URL.
// The record exposes name(), username(), password(), jdbcUrl(), implementation() and schema().
// databaseTypeName() returns the Hop DatabaseMeta type: "H2" or "ORACLE".
spec -> src.databaseTypeName();
}
BaseDatabaseExtension (SPI)
Implement this class (package io.yupiik.hop.junit.database) and register it in META-INF/services/io.yupiik.hop.junit.database.BaseDatabaseExtension to provide a new backend:
-
name()- matchesDatabaseImplementation.current()("H2","ORACLE", ...); -
findDatabases(context)- the ordered, de-duplicated descriptors the method declares; -
createDatabase(context, descriptor)- open the physical database, return spec + connection; -
seedDataset(managed, inits)/verifyDataset(managed, expected)- the dataset engine hooks; -
optionally
beforeDatabases,resetDatabase,provisionAdminfor backend-specific lifecycle.
The base class implements the whole JUnit lifecycle (schema creation, seeding, verification after a passing test, close + reset) and the @JdbcNamed parameter resolution. The isolated Hop working tree per test is prepared by the @HopPipeline / @HopWorkflow extensions (HopTestWorkDirectories), not by the database backend, so the two responsibilities stay decoupled.
Configuration surface
| Property | Default | Description |
|---|---|---|
|
|
|
Which registered backend the |
|
|
|
H2 compatibility mode for |
|
|
pinned digest |
Testcontainers image for the Oracle backend. The key derives from the backend's simple class name minus |
|
|
|
Base dir for the isolated Hop work tree. When set by the IDE (rather than Maven), pass it through surefire with |