This question is aimed at finding out people’s approaches / recommendations for good practice, than a call for help.
I have a binary that loads configuration / assets, which should be next to the binary when installed. In development, the built binary lives in
I want to be able to run
cargo test [--release] to test different sets of configuration.
Approach I’ve taken:
- In unit tests, I make an intermediate function which lets me pass in
PathBufso I can inject a path to a fake exe parent directory, to point it to a tempdir. The delta between the test code and the real code is “how to calculate the parent directory”.
I want to run
cargo run [--release] without additional “fluff”. Additional “fluff” being copying configuration to the
target/<profile> directory. I don’t want to do that because:
- It’s incovenient / easy to forget a step / have stale config.
- It’s not isolated if I wanted to run things in parallel, e.g. have integration tests that execute
#[cfg(test)]mode, or when using the
debugprofile, tell the application to also search
option_env!("CARGO_MANIFEST_DIR")for default config.
When using the
releaseprofile, look up an
APP_DIRenvironmental variable to substitute the application’s parent directory.
The environmental variable allows the code to not contain information about the build environment, as well as allows tests in the
tests/directory to do something like:
cargo run [--release].
- Do assertions on the actual binary that will be released.
Humans still have to go
export APP_DIR=`pwd`; cargo run --releaseto use the crate dev config.
This does introduce an additional
APP_DIR input to the application. I guess
git does allow you to do something similar through its
When running unit tests in the
release profile, library dependencies are not
cfg(test), even if they are in the same crate workspace, so they don’t pass the
cfg!(test) check to use dev config.
That’s hard to understand in words, so here is a diagram:
// A -> B means A depends on B lib_a -> lib_b -> lib_macro
lib_macroprovides a macro to load configuration from the current crate directory if it’s in
lib_bloads configuration type
lib_a to store configuration for
lib_b for tests. In
cargo test, it loads fine from
lib_a's crate directory because
lib_b is compiled using the
debug profile. However when using
cargo test --release, it doesn’t load fine, because in
lib_macro doesn’t insert the
CARGO_MANIFEST_DIR value as a base directory (to prevent leaking development values).
So, the approach I took was:
APP_DIRenvironmental variable during tests.
This didn’t feel clean, I don’t know why.