[][src]Macro testdir::testdir

macro_rules! testdir {
    () => { ... };
    ( TestScope ) => { ... };
    ( ModuleScope ) => { ... };
    ( $e:expr ) => { ... };
}

Creates a test directory at the requested scope.

This macro creates a new or re-uses an existing NumberedDir for the current user. It than creates the requested sub-directory within this NumberedDir. The path for this directory is returned as a PathBuf.

For the typical testdir!() invocation in a test function this would result in /tmp/testdir-of-$USER/$CARGO_PKG_NAME-$N/$CARGO_CRATE_NAME/module/path/to/test_function_name. A symbolic link to the most recent NumberedDir is also created as /tmp/testdir-of-$USER/$CARGO_PKG_NAME-current -> $CARGO_PKG_NAME-$N.

Reuse of the NumberedDir is triggered when this process is being run as a subprocess of Cargo, as is typical when running cargo test. In this case the same NumberedDir is re-used between all Cargo sub-processes, which means it is shared between unittests, integration tests and doctests of the same test run.

The path within the numbered directory is created based on the context and how it is invoked. There are several ways to specify this:

  • Directly provide the path using an expression, e.g. testdir!("sub/dir"). This expression will be passed to [NumberedDir::create_subdir] and thus must evaluate to something which implements AsRef, e.g. a simple "sub/dir" can be used or something more advanced evaluating to a path, usually [Path] or [PathBuf`].

  • Use the scope of the current test function to create a unique and predictable directory: testdir!(TestScope). This is the default when invoked as without any arguments as well: testdir!(). In this case the directory path will follow the crate name and module path, ending with the test function name. This also works in integration and doctests.

  • Use the scope of the current module: testdir!(ModuleScope). In this case the crate name and module path is used, but with an additional final mod component.

Panics

If there is any problem with creating the directories or cleaning up old ones this will panic.

Examples

Inside a test function you can use the shorthand:

use std::path::PathBuf;
use testdir::testdir;

let path0: PathBuf = testdir!();

This is the same as invoking:

let path1 = testdir!(TestScope);

These constructs can also be used in a doctest.

The module path is valid in any scope, so can be used together with once_cell (or lazy_static) to share a common directory between different tests.

use std::path::PathBuf;
use once_cell::sync::Lazy;
use testdir::testdir;

static TDIR: Lazy<PathBuf> = Lazy::new(|| testdir!(ModuleScope));

#[test]
fn test_module_scope() {
    assert!(TDIR.ends_with("mod"));
}