Problem using external modules inside integration test submodule


#1

I have library project with submodule:

src/lib.rs:

extern crate hyper;
mod bar;
pub fn foo() {
    let _h = hyper::Url::parse("http://example.com");
    bar::bar();
}

src/bar.rs:

use hyper;
pub fn bar() {
    let _url = hyper::Url::parse("http://example.com");
}

Cargo.toml:

[package]
authors = ["Mikhail Trishchenkov <kriomant@gmail.com>"]
name = "testmod"
version = "0.1.0"

[dependencies]
hyper = "0.8.0"

I can build it just fine.

Now I create tests directory and copy lib.rs and bar.rs to it.
And tests can’t be built:

   Compiling testmod v0.1.0 (file:///Users/kriomant/Temp/testmod)
tests/bar.rs:1:5: 1:10 error: unresolved import `hyper`. There is no `hyper` in `???` [E0432]
tests/bar.rs:1 use hyper;
                   ^~~~~
tests/bar.rs:1:5: 1:10 help: run `rustc --explain E0432` to see a detailed explanation
error: aborting due to previous error
Build failed, waiting for other jobs to finish...
Could not compile `testmod`.

To learn more, run the command again with --verbose.

Why?


How to use external crate in Cargo integration tests?
#2

… why would you copy your library’s source into the tests directory in the first place? I’m confused as to what you’re trying to accomplish.

It doesn’t work because the tests directory is for tests, not a copy of your library source code. Each source file is assumed to be an independent test program, so bar.rs is being compiled by itself.

Normally, you’d write integration tests that link to the library you’ve written and invoke it like any other external code would.

Also, on the chance you haven’t already, you should read the Testing chapter of the Rust Book.


#3

http://doc.crates.io/manifest.html#integration-tests:

Each file in tests/*.rs is an integration test. When you run cargo test, Cargo will compile each of these files as a separate crate.

So your lib.rs and bar.rs are being treated as two separate integration tests; since bar.rs does not itself contain an extern crate declaration, it fails to compile.


#4

Oh, they are all separate crates. Got it. Thanks.

But how can I share testing helper functions between integrations tests?


#5

And I think https://doc.rust-lang.org/book/testing.html should be modified to note that. Because it says “tests in the tests directory are an entirely separate crate”, but it isn’t obvious that each file is separate crate.


#6

http://doc.crates.io/manifest.html#integration-tests

Cargo will not automatically compile files inside subdirectories of tests, but an integration test can import modules from these directories as usual. For example, if you want several integration tests to share some code, you can put the shared code in tests/common/mod.rs and then put mod common; in each of the test files.

I agree it should be easier to find. Took me fifteen minutes to find that, and I’m not quite new. (One or the other of us could make up a documentation PR; those tend to be well received.)


#7

Cool. Thank you.