Explicit `test` target in `Cargo.toml` interfering with `exclude` directive

Suppose I have a project structure like this:

Cargo.lock
Cargo.toml
src
src/lib.rs
tests
tests/atest.rs

and I have a Cargo.toml that looks like this:

[package]
name = "my-problem"
version = "0.1.0"
edition = "2021"
exclude = ["tests/*"] # <<< tests directory is excluded from packaging...

[dependencies]

[[test]]
name = "atest" # <<< but my integration test has a deliberate entry

If I run cargo package, I get this error:

❯ cargo package --allow-dirty
warning: manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
   Packaging my-problem v0.1.0 (/Users/ken.swanson/test/my-problem)
   Verifying my-problem v0.1.0 (/Users/ken.swanson/test/my-problem)
error: failed to verify package tarball

Caused by:
  failed to parse manifest at `/Users/ken.swanson/test/my-problem/target/package/my-problem-0.1.0/Cargo.toml`

Caused by:
  can't find `atest` test at `tests/atest.rs` or `tests/atest/main.rs`. Please specify test.path if you want to use a non-default path.

The problem seems to be the explicit [[test]] target for atest in Cargo.toml; if that section is removed, then cargo build, cargo test, and cargo package all work as expected; it's only when explicitly trying to specify the test that package fails.

Is there any way to tell Cargo not to check for the existence of a target (i.e., [[test]]) when packaging?

The reason I ask is that I'm publishing a new version of a crate with features, and we moved some of our tests behind those features, so I added [[test]] entries to our Cargo.toml with required-features entries to make those tests compile correctly. I suspect our answer will be to just remove the tests directory from our list of excludes but I wanted to check for all options.

Include the tests in the package.

This doesn't just solve your problem, it helps the ecosystem:

  • Someone having unusual trouble using your package (perhaps with a newer version of rustc or your dependencies than existed when you published it) can run the tests and confirm that they in fact pass (or don't).
  • Crater will run your tests, helping validate future Rust versions. (It might already be finding your public repository if you have one, though.)
2 Likes

I understand that that's the best solution, and it is what I ended up doing; but if I didn't want to include the test in the package, is there a way around this?

You could put all the actual test code in modules and exclude those files, but not the tests/atest/main.rs root file.

Hrm...that's an interesting thought.

In the end I got the okay to just include the tests, but I'll keep that in mind. Thanks!