#integration-tests #test

test-patience

Synchronize the startup of applications that are part of an integration test

2 releases

Uses old Rust 2015

0.1.1 Mar 24, 2017
0.1.0 Jan 28, 2017

#965 in Testing

MIT license

9KB

test-patience

Build Status Windows build status Crate version Documentation

test-patience is a utility to synchronize the startup of applications that are part of an integration test and the test itself.

When writing integration tests, it is often necessary to launch applications that are part of the test. This can take some time and if the test has to wait until the application is running, valuable time is lost when waiting for a fixed duration. Also waiting for a fixed duration can still lead to test failures without producing a clear error message. test-patience waits exactly until the starting application signals that it's ready or a specified timeout period has passed.

The test has to create an instance of the Server struct, which starts a TCP server and returns a port number. That port number needs to be sent to the application that is needed to execute the test. This could be done using an environment variable, an argument or a configuration file. After the start of the application has been initiated, the wait method needs to be called. It blocks the currently running thread until either the starting application has signaled its successful start or the timeout period has passed.

When the application is ready, it has to create an instance of the Client struct and call the notify method with the correct port number. After that the thread of the test continues executing.

In order to disable startup notifications in release builds, use cfg!(debug_assertions) (see conditional compilation).

Examples

Application

use std::env;

// initialize application (eg. connect to database server)
let db_connection = get_db_connection();

// notify test in case the environment variable TEST_PATIENCE_PORT is set
if let Some(port) = env::var("TEST_PATIENCE_PORT").ok()
                    .and_then(|s| s.parse::<u16>().ok()) {
    test_patience::Client::notify(port).unwrap();
}

Test

use std::time::Duration;
use std::process;

let server = test_patience::Server::new().unwrap();
let port = server.port().unwrap();

let process = process::Command::new("path/to/application")
    .env("TEST_PATIENCE_PORT", format!("{}", port))
    .spawn()
    .unwrap();

server.wait(Duration::from_secs(5)).unwrap();

No runtime deps