I want to run tests and benchmarks against a pre existing datasource. All the data is stored in a directory inside my project folder. What is the best way to use this directory in my tests and benchmarks?
This is what I am currently doing:
let path: PathBuf = env::current_exe().unwrap()
.parent().unwrap()
.parent().unwrap()
.parent().unwrap()
.parent().unwrap()
.join("data");
I feel like this is a fragile and ugly solution. Is there a better way of doing this?
If the data is small enough to fit in memory, you can use include_bytes!() to embed it in the benchmark executable. The path will be relative to the source file, so it's usually more reliable.
For a real-world example of this, have a look at the integration tests for the gcode crate.
I've stored a bunch of example gcode programs under tests/data/ and smoke_test.rs uses concat!() and env!("CARGO_MANIFEST_DIR") to construct the path passed to include_str!() for embedding the file contents in the test binary.
Unfortunately my tests just a large amount of files so it wouldn't be practical to use include_str!() or include_bytes!(), but I will definitely look into the environment variables.
Shameless plug: I created a crate called include-dir-macro that lets you include the contents out a large number of files at compile time. It's not perfect, but it should do what you need.
You can figure out fixture's filename using env!("CARGO_MANIFEST_DIR") and some_path_buf.join(), so why not just read the data with std::fs::File like a normal file?
To add to this, another alternative is the include_dir crate. I believe that both use include_bytes!() to embed directory tree's contents into the test binary at compile time though, which may or may not work for your use case.