8 releases (5 breaking)
0.6.0 | Oct 9, 2024 |
---|---|
0.5.1 | Jul 23, 2024 |
0.5.0 | Feb 27, 2024 |
0.4.1 | Sep 25, 2023 |
0.1.0 | Apr 12, 2023 |
#363 in Testing
984 downloads per month
41KB
624 lines
Allows your integration tests to run your application under a separate process and assert on tracing
events.
To achieve this, it locates or builds the application's executable,
runs it with tracing
in JSON mode,
and then processes the JSON logs to both assert on and display in human readable form.
It is a little opinionated and by default will fail the test when a tracing
warning or error occurs.
However a specific warning or error can be allowed on a per test basis.
Example usage for an imaginary database project named cooldb:
use tokio_bin_process::event::Level;
use tokio_bin_process::{BinProcess, bin_path};
use tokio_bin_process::event_matcher::EventMatcher;
use std::time::Duration;
use std::path::PathBuf;
/// you'll want a helper like this as you'll be creating this in every integration test.
async fn cooldb_process() -> BinProcess {
// start the process
let mut process = BinProcess::start_binary(
// Locate the path to the cooldb binary from an integration test or benchmark
bin_path!("cooldb"),
"cooldb", // The name that BinProcess should prepend its forwarded logs with
&[
// provide any custom CLI args required
"--foo", "bar",
// tokio-bin-process relies on reading tracing json's output,
// so configure the application to produce that
"--log-format", "json"
],
)
.await;
// block asynchrounously until the application gives an event indicating that its ready
tokio::time::timeout(
Duration::from_secs(30),
process.wait_for(
&EventMatcher::new()
.with_level(Level::Info)
.with_target("cooldb")
.with_message("accepting inbound connections"),
&[]
),
)
.await
.unwrap();
process
}
#[tokio::test]
async fn test_some_functionality() {
// start the db
let cooldb = cooldb_process().await;
// connect to the db, do something and assert we get the expected result
perform_test();
// Shutdown the DB, asserting that no warnings or errors occured,
// but allow and expect a certain warning.
// A drop bomb ensures that the test will fail if we forget to call this method.
cooldb
.shutdown_and_then_consume_events(&[
EventMatcher::new()
.with_level(Level::Warn)
.with_target("cooldb::internal")
.with_message("The user did something silly that we want to warn about but is actually expected in this test case")
])
.await;
}
When Cargo builds integration tests or benchmarks it provides a path to the binary under test.
We can make use of that for speed and robustness with BinProcess::start_binary
.
But that is not always flexible enough so as a fallback BinProcess
can invoke Cargo again internally to ensure the binary we need is compiled via BinProcess::start_binary_name
.
Dependencies
~7–17MB
~212K SLoC