libcnb-test
An integration testing framework for Cloud Native Buildpacks written in Rust with libcnb.rs.
The framework:
- Automatically cross-compiles and packages the buildpack under test
- Performs a build with specified configuration using
pack build
- Supports starting containers using the resultant application image
- Supports concurrent test execution
- Handles cleanup of the test containers and images
- Provides additional test assertion macros to simplify common test scenarios (for example,
assert_contains!
)
Dependencies
Integration tests require the following to be available on the host:
- Docker
- Pack CLI
- Cross-compilation prerequisites (however
libcnb-cargo
itself is not required)
Only local Docker daemons are fully supported. As such, if you are using Circle CI you must use the
machine
executor rather than the
remote docker feature.
Examples
A basic test that performs a build with the specified builder image and app source fixture,
and then asserts against the resultant pack build
log output:
// In $CRATE_ROOT/tests/integration_test.rs
use ;
// Note: In your code you'll want to uncomment the `#[test]` annotation here.
// It's commented out in these examples so that this documentation can be
// run as a `doctest` and so checked for correctness in CI.
// #[test]
Performing a second build of the same image to test cache handling, using [TestContext::rebuild
]:
use ;
// #[test]
Testing expected buildpack failures, using [BuildConfig::expected_pack_result
]:
use ;
// #[test]
Running a shell command against the built image, using [TestContext::run_shell_command
]:
use ;
// #[test]
Starting a container using the default process with an exposed port to test a web server, using [TestContext::start_container
]:
use ;
use thread;
use Duration;
const TEST_PORT: u16 = 12345;
// #[test]
Inspecting an already running container using Docker Exec, using [ContainerContext::shell_exec
]:
use ;
// #[test]
Dynamically modifying test fixtures during test setup, using [BuildConfig::app_dir_preprocessor
]:
use ;
use fs;
// #[test]
Building with multiple buildpacks, using [BuildConfig::buildpacks
]:
use buildpack_id;
use ;
// #[test]
Tips
- Rust tests are automatically run in parallel, however only if they are in the same crate. For integration tests Rust compiles each file as a separate crate. As such, make sure to include all integration tests in a single file (either inlined or by including additional test modules) to ensure they run in parallel.
- If you would like to be able to more easily run your unit tests and integration tests
separately, annotate each integration test with
#[ignore = "integration test"]
, which causescargo test
to skip them (running unit/doc tests only). The integration tests can then be run usingcargo test -- --ignored
, or all tests can be run at once usingcargo test -- --include-ignored
. - If you wish to assert against multi-line log output, see the indoc crate.