install4j Help

API for installer UI tests

The install4j test API drives an actual installer UI from inside a test JVM. It lets you write automated end-to-end tests that exercise an installer, drive its screens and dialogs, and verify post-install state. The API is framework-agnostic: any test runner (JUnit, TestNG, Spock, plain main) works because it only exposes a session API.

Use it when you need to assert that an installer reaches the expected screens and writes the expected files, variables and configuration. For pure unattended-mode regression checks, the generated installer with the -q flag is sufficient in which case this API is not required.

The complete API documentation is in the com.install4j.api.test package. The test API is built on top of the installer API. Sessions expose the com.install4j.api.context.Context and the com.install4j.api.context.WizardContext of the running installer.

Development environment

The test API ships as a separate Maven artifact with these coordinates:

group: com.install4j
artifact: install4j-test
version: <install4j version>

where the install4j version corresponding to this manual is 13.0. Add it to the test classpath only:

<dependency>
    <groupId>com.install4j</groupId>
    <artifactId>install4j-test</artifactId>
    <version>13.0</version>
    <scope>test</scope>
</dependency>

Jar, source and Javadoc artifacts are published to the Maven Central repository. If a Maven dependency is not an option, the JAR file ships under

resource/install4j-test.jar

in the install4j installation, alongside resource/i4jruntime.jar. Both are required on the test classpath.

Sessions

A session is the running installer, uninstaller or custom installer application process under test, wrapped as an java.lang.AutoCloseable. The three session types are:

  • InstallerSession
    Drives an installer from a generated media file. Created with InstallerSessionBuilder.forMediaFile(media).
  • UninstallerSession
    Drives the uninstaller of an already installed installation. Created with UninstallerSessionBuilder.forInstallation(installDir).
  • InstallerApplicationSession
    Drives a custom installer application (update downloader, custom maintenance tool) from an already-installed copy. Created with InstallerApplicationSessionBuilder.forInstallation(installDir).applicationId(id).

All three implement com.install4j.api.test.session.Session, which provides the waits, screen and dialog accessors, variable access, log access, and lifecycle methods. The builders are fluent and let you set the default timeout, system properties, working directory, log file and command-line arguments before starting the session. See the com.install4j.api.test.session package for the full API.

It is recommended to use try-with-resources on the session. Closing a session terminates the installer thread, clears the extraction cache and deletes the auto-created installation directory if the session itself created it. User-supplied directories are not deleted.

Driving the wizard

The com.install4j.api.test.ui.ScreenHandle returned from session.currentScreen() or session.waitForScreenId(id) is the central entry point for driving the wizard. It exposes typed accessors for every install4j form component, Next/Previous/Cancel/Finish buttons of the wizard, and UI diagnostics via com.install4j.api.test.ui.UiContainer.

Each form-component accessor returns a typed handle with the operations specific to that component, for example textField("24").setText(...) or checkBox("31").assertNotSelected().setSelected(true). The handles also expose typed asserts that return the handle for chaining. See the com.install4j.api.test.formcomponents package for the complete catalogue.

Every form-component accessor comes in two flavors: a single-argument form that takes the configured form-component id, and a no-arg form that returns the unique handle of that type on the current screen. Screen ids are the values configured in the install4j IDE: the Customized id if set, otherwise the integer id.

Modal dialogs

The wizard may show modal dialogs for alerts, file choosers, the startup language selection, password prompts and similar. The com.install4j.api.test.session.Session interface has a typed accessor for each such dialog (session.alert(), session.fileChooser(), session.languageDialog() and others) that blocks until the matching dialog is showing and returns a dedicated handle. A generic session.dialog(predicate) accessor matches windows shown by custom code or extensions. See the com.install4j.api.test.ui package for the complete dialog handle API.

Asserting state

Once the installer has reached a terminal screen and exited, sessions expose everything needed to verify what the installer did:

  • Installer variables
    session.getVariable(name) returns the value of any installer variable captured at the time the installer exits.
  • Installer log
    session.getLogFile() and session.readLog() give access to the full installer log for assertions or debugging.
  • Filesystem
    Inspect the installation directory directly.
  • Exit code
    session.awaitExit() blocks until the installer thread exits and returns its exit code.

Wait operations that time out throw a typed com.install4j.api.test.InstallerTestException subtype. The full list of exception types is in the com.install4j.api.test.exceptions package.

How the installer runs

By default the test API launches the produced installer media as a subprocess and drives it from the test JVM over IPC. The bundled JRE, the native launcher and the actual classloader hierarchy are exercised as in a real installation. The same applies to com.install4j.api.test.session.UninstallerSession and com.install4j.api.test.session.InstallerApplicationSession where the test API locates the matching launcher inside the installation directory.

On Linux without a usable DISPLAY, the test API wraps the spawned installer subprocess in xvfb-run plus a reparenting window manager (metacity, mutter, openbox, fluxbox or marco) itself. Install one of those as well as xvfb-run to run UI tests on a CI machine.

In-process debug mode

SessionBuilder.debug(true) switches the session to an in-process execution where the installer runs inside the test JVM. This mode requires media built with install4jc -g (or --debug) on the install4jc invocation, which additionally produces a debug_<media-name>/ directory next to the media file with the content already unpacked. The test API throws com.install4j.api.test.InstallerTestException if the directory is missing. Use this mode to speed up edit-recompile-test loops or to debug the test.

Limitations

The test API handles a language selection in-process in both modes, while the normal execution will restart the installer with the correct locale set on the command line. This means that locale-specific features for a non-primary language may be different in the test modes.

Kotlin extensions

The com.install4j.api.test.session package adds idiomatic block-scoped Kotlin helpers on top of com.install4j.api.test.session.Session: One session.onXxx { ... } wrapper per screen and dialog type, plus session["varName"] as the operator form of session.getVariable. See the com.install4j.api.test.session package overview for the full list.