Liquibase SDK Test Environments
Overview
To make it easy to spin up standardized test environments for testing, Liquibase has an abstraction around testcontainers.org at liquibase/extension/testing/testsystem.
The wrapper around Test Containers allows us to provide a simple configuration system, plus support testing databases that do not have Docker containers such as in-memory and cloud databases.
Note
The SDK Test Environment System is currently only available in the main Liquibase repository, not for extensions.
Configuration
The default test environments and settings are configured in liquibase-extension-testing/src/main/resources/liquibase.sdk.yaml.
That file configures the various databases including docker image settings and users to create. Generally, each test system will be created with:
- A
lbuser
user with a passwordLiquibasePass1
- A catalog/database called
lbcat
- An alternate catalog/database named
lbcat2
- An alternate schema named
lbschem2
Besides the environment configuration, the default setup also sets the liquibase.sdk.testSystem.test
configuration to h2,hsqldb,sqlite
. This setting controls which databases are tested against and which are skipped. Note that by default only in-memory databases will be used.
Custom Configuration
The SDK Test Environment setup looks up configuration keys in:
- System properties
- Environment Variables
- A
liquibase.sdk.local.yaml
file - A
liquibase.sdk.yaml
file
If a configuration is set in multiple locations, it will use the value it finds first given the above order.
For example, by default the MysqlIntegrationTest will skip all tests because liquibase.sdk.testSystem.test
does not include "mysql". To customize that configuration, you could:
- Add a
-Dliquibase.sdk.testSystem.test=mysql
argument to your java call. This works well when running specific tests from your IDE's "test run" configuration which you don't always want to enable - Add a
LIQUBASE_SDK_TEST_SYSTEM_TEST=mysql
environment variable. This works like a system property but may be easier to set depending on how you are working - Create a liquibase.sdk.local.yaml file in
liquibase-extension-testing/src/main/resources
next toliquibase.sdk.yaml
. This file is not checked into git, and works well for more permanent/consistent changes you would like to make
Configuration Structure
All settings for the test environments use the liquibase.sdk.testSystem
prefix. The overall structure can be seen in the liquibase-extension-testing/src/main/resources/liquibase.sdk.yaml file.
For each test environment, there is a top-level "key" for it. For example, liquibase.sdk.testSystem.mysql
. There is also a liquibase.sdk.testSystem.default
section which contains default/standard settings.
When code is looking for a particular setting such as liquibase.sdk.testSystem.mysql.username
it will first look for liquibase.sdk.testSystem.mysql.username
in all the locations it could be set
and if none has that setting, it will look for liquibase.sdk.testSystem.default.username
in those same locations.
This allows common settings such as "username" to be shared across environments while keeping environment-specific settings like "imageName" separate.
Example liquibase.sdk.local.yaml File
Anything you set in liquibase.sdk.local.yaml
file will override what is in the default liquibase.sdk.yaml
file, but there is no need to duplicate settings from the liquibase.sdk.yaml
file.
Copy/pasting settings from the default only risks unexpected drift between what you are testing against and what others use.
Example file:
liquibase:
sdk:
testSystem:
test: h2,mysql,postgresql
mysql:
version: 8.0
This changes what databases are tested against to be only h2, mysql, and postgresql without changing what is tested against. It also changes the mysql version to test to "8.0" regardless of what the default is.
Starting Databases
In Tests
Tests can auto-start databases on demand when they are run.
A call to
Scope.getCurrentScope().getSingleton(TestSystemFactory.class).getTestSystem("mysql")
will either return the database connection after starting the database OR throw a AssumptionViolatedException
exception which causes the test to be skipped.
The liquibase.sdk.testSystem.test
setting controls which environments to auto-start and which to skip.
The AbstractIntegrationTest
base class contains this logic for the classic integration tests.
On-Demand
To start and stop test systems manually, you can use the liquibase sdk system up
and liquibase sdk system down
commands.
NOTE: these commands are part of the liquibase-extension-testing
module and are not currently shipped as published artifacts.
Therefore, to use them you must either:
- Run
mvn package
from the root of the Liquibase repository and copyliquibase-extension-testing/target/liquibase-extension-testing-0-SNAPSHOT.jar
to your LIQUIBASE_HOME/lib directory - From your IDE, run
liquibase.integration.commandline.LiquibaseLauncher
using theliquibase-extension-testing
classpath
The "up" and "down" commands let you start and top the test environments as needed.
Any tests you run will use these manually started environments rather than creating their own.