Dependency issue with separate test crate

I have two crates:

  • mycrate
  • mycrate-test

The mycrate cargo config has a line like this:

[dev-dependencies]
mycrate-test = "0.1.0"

The mycrate-test cargo config has a line like this:

[dependencies]
mycrate = "0.1.0"

The reason being that mycrate-test has some helper functions that need to import some traits from mycrate to work properly. The problem is that this structure seems to be creating two different versions of mycrate. In particular, cargo now complains that any references to types being used in mycrate-test that originate from mycrate are not interoperable (i.e. the mycrate:Error being returned from a function in mycrate-test is not the same type as the one in the main crate).

I understand this is a strange relationship, but I'm wondering if there's a way to make this work or if I need to reconsider breaking my helper functions out into a different crate.

Are you using the same mod foo; statements in both crates? If so, you have to replace them in mycrate-test with use mycrate::path::to::foo, possibly making some items pub.

This previous topic might be relevant: Problems sharing test code (traits) via a testutils crate

Could you explain this?

Change these unit tests into integration tests. Then they will link to the core library from step 1, just like the testutils crate does, so both of them will use the same copy of the BuiltinCommand trait. (However, integration tests can't directly test private code from the core library.)

In my case I am only running integration tests in mycrate and am still running into the same issue mentioned in that thread.

It would be useful to see the full error message, perhaps with verbose Cargo output (cargo -v) to see how the compiler is being invoked when the error happens.

Here you go.

In the above output, the two crates are vaultrs and vaultrs-test.

Thanks. This looks like a different problem than in that previous thread I linked, so those suggestions probably won't help. I can't tell from the error what the actual problem is, though...

Just to double-check, are there any source files being included more than once, perhaps by multiple mod foo; items as @Cerber-Ursi suggested above?

Oh wait, I see the problem. The mycrate-test manifest depends on mycrate from crates.io:

[dependencies]
mycrate = "0.1.0"

So Cargo downloads and builds the published crates.io version of mycrate, then it builds mycrate-test and links it to that version, then it builds your local copy of mycrate.

You can fix this by adding a path to both Cargo dependencies. Cargo will use the path when building from a local source tree, and the version when building a downloaded package.

mycrate-test/Cargo.toml:

[dependencies]
mycrate = { version = "0.1.0", path = "../path/to/mycrate" }

mycrate/Cargo.toml:

[dev-dependencies]
mycrate-test = { version = "0.1.0", path = "path/to/mycrate-test" }

Hmm, how does this affect the repository layout? For example, these crates are in different repos (vaultrs and vaultrs-test) but assuming a local path means anyone wanting to test vaultrs would need to know to clone vaultrs-test into the parent directory? Or are you suggesting bringing the vaultrs-test crate into the same repo as vaultrs?

Putting them in the same repo would definitely make local development easier when you have circular dependencies like this. Otherwise, each developer who wants to test locally needs to set up their own overrides to point the two crates at each other.

I'm not opposed to that. Thanks for the help!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.