Integration Tests and Importing Self Crate

Hello Rustaceans,

I'm working on my ToDo Crate and I've gotten to the point of wanting to write integration tests, since I plan to use Test Drive Development (TDD) to complete the project.

In the Rust Book, all it says is "Integration tests are external to your crate and use only its public interface in the same way any other code would"

So does this mean in order to write an integration test I have to:

  1. Publish the project to crates.io
  2. Add my own crate as a dependency in the Cargo.toml file
  3. and download the whole project

in order for use ClearHeadTodo to work despite the code only being over one folder?

I feel like there should be an immediate way to do it, but if this is how it's supposed to work, it would be good to know that from the community.

As always, thank you for your time and expertise!

You don't need to publish your crate on crates.io to test it. You just need to import items from your crate as if you had specified it as a dependency.

1 Like

Typically you just put the test in the tests/ directory next to src/ and run cargo test.

Then the use piece above should work shouldn't it? when I use a use, the same way that I did between lib and main.rs, it simply throws a "Unresolved import ClearHeadToDo" Error.

I've encapsulated everything in a CLI Struct in main.rs. do I need to put this struct in a module? or do I just import the struct itself like I did in main.rs?

Thank you for your patience.

I've built unit tests in lib.rs for all the logic in there.

The question is how do I import the code from src/main.rs -> tests/integration_tests.rs?

You cannot. Integration tests are meant to test the library, i.e. everything starting from lib.rs, and not the binary. It's common, however, to have almost all the logic in library, and then write binary as a thin wrapper around it.

1 Like

Interesting, so the main file just isn't intended to be unit tested? I've been writing all my unit tests in lib.rs, but it makes me wonder what the tests/ folder is intended for?

It can be unit tested, by writing #[test] functions in it. But integration tests, placed in tests/, are meant to test your library, by depending on it and pretending they're just another binary it is linked to.

1 Like

In summary, unit tests are expected to be separate tests within the code; integration tests are outside the code because they test how well the code integrates with other things.

1 Like

Thanks everyone,

This is making more sense. Then i suppose technically i've been doing only integration tests since I already have a block of code in lib.rs which starts with super::* and tests all of these functions as integrations.

Follow-up then: Does that mean best-practice for normal tests is to put it with production code? like should i consider putting my tests in the same impl block as the struct functions?

Thank you everyone for your patience and knowledge.