Describe the problem you are trying to solve
It might be a very frustrating experience for a newbie to read about integration tests, placing tests under tests/integration.rs, trying to import the main crate, only to find a cryptic message that the "crate is not found".
Here's an example:
error[E0463]: can't find crate for `example_binary`
--> tests/integration.rs:1:1
|
1 | extern crate example_binary;
| ^^^^^^^^^^^^^^^^^^^^ can't find crate
error: aborting due to previous error
Describe the solution you'd like
In the spirit of Rust's helpful error messages, it would be good to have something in the vein of "help: actually, the crate example_binary exists, but it's a binary crate, so it can't be imported. If you want to test its functionality by calling it from Rust code, try to separate the APIs you want to test into a separate library, (a link to documentation that explains main.rs and lib.rs), with the relevant functions and types exported with pub."
Notes
Of course, even more desirable thing here would be if it Simply Worked. For example, I kind of expected that you could call functions with pub even from a binary main.rs.
I feel like your issue is similar to mine for an improvement in The Rust Book - https://github.com/rust-lang/book/issues/1940. It got a few voices of support, but unfortunately was closed. It seems to me this is a problem more people get exposed to and should be addressed.
I also ran into a similar issue today. I was building a crate-type = ["cdylib"] and tried to use extern crate my_package but got the same error and couldn't figure out why. Now that I know the fix, it totally makes sense, but the error messages left a little confused.
For now, I'll just comment that line out when I run integration tests.
I've just spent 4hrs reading docs and shuffling files in a project with no luck, until I've found this post...
Also building cdylib, which is technically a lib... anyways...
Thanks guys for hints.
The error message is extremely confusing, and the fact that binary crates cannot be tested is unintuitive and guaranteed to confuse every single person who runs across this problem. Why can't binary crates be tested at an internal API level?
I'm exactly in that situation and I don't understand what I'm supposed to do. Have a lib.rs AND a main.rs? I don't get it.
I'm exactly in that situation and I don't understand what I'm supposed to do. Have a
lib.rsAND amain.rs? I don't get it.
@EpiFouloux There is an alternative to splitting up your project into a lib and a binary. Just put the test into your source tree. For example, suppose you have a file called frob.rs that implements various functions you want to test. Then, at the bottom of frob.rs, append the following:
#[cfg(test)]
mod tests {
// Test in-file as we cannot test on a binary crate level
use super::*;
#[test]
fn test_frob_operation() {
// Insert your assertions here. You may use any of the functions defined in this file.
assert_eq!(1, 1);
}
}
These tests will not be compiled into the release binary, but they will be compiled and run if you execute cargo test, the output looks as following:
Finished test [unoptimized + debuginfo] target(s) in 1.45s
Running target\debug\deps\testcrate-619e72657b7037dd.exe
running 1 test
test tests::test_frob_operation ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
I chose this option and it works well for me.
@BenjaminRi What you described is a unit test, while the questions in this thread were about integration tests. Note that the code undercfg(test) is not compiled in the latter.
What I ended up doing and that works is keeping only my main.rs, having my "tests" folder under src but adding #[cfg(tests)] above mod tests; in main.rs.
All integration tests work and the cargo build doesn't check errors and warns under that folder.
@EpiFouloux That sounds like unit tests, not integration ones, because in the latter cfg(tests) is not compiled. Can you try what I described in https://github.com/rust-lang/book/issues/1940?
Yes that seems like a good solution, but what are those make_binary_testableuses?
@EpiFouloux For clarity I changed them into "my_library" - it's just the name of your project you are working on, structured as a library. That library can then be used in a binary or in integration tests.
Most helpful comment
I've just spent 4hrs reading docs and shuffling files in a project with no luck, until I've found this post...
Also building
cdylib, which is technically a lib... anyways...Thanks guys for hints.