I still don't understand the project structure and how to import your own crate for integration tests

I get that for integration test I would need to create a src/lib.rs file
and move src/main.rs contents to src/lib.rs, but other than that, I'm clueless.

error[E0433]: failed to resolve: could not find `shared` in the crate root
 --> tests/test.rs:6:12
  |
6 | use crate::shared::constants::command::SUDO;
  |            ^^^^^^ could not find `shared` in the crate root

For more information about this error, try `rustc --explain E0433`.

src/main.rs

fn main -> Result<()> {
    let mup app = App::new();
    app.run()
}

tests/test.rs

use crate::shared::constants::command::SUDO;

#[test]
fn test_run() {
    let home_dir = format!("/home/user");
    let home_path = Path::new(home_dir);

    // Todo: run my_capp methods that create home_path
    assert_eq!(home_path.exists(), true)
    assert_eq!(SUDO, "sudo");
}

Cargo.toml

[package]
name = "my_app"
version = "0.1.0"
edition = "2021"
authors = ["Folaht"]

Integration tests are meant for testing the public API your library exposes. Therefore you need to make sure the items you want to use in your integration tests are public and import them like your library crate is just another external dependency, i.e. by replacing the leading crate in your path with the name of your library (which defaults to your package name with dashes becoming underscores):

- use crate::shared::constants::command::SUDO;
+ use my_app::shared::constants::command::SUDO;
1 Like

Now I'm beginning to question whether what I want is an integration test or a unit test.

I want to test "a bunch of button press sequences",
so I'll know my app continues to work when I maintain it.
Is that an integration test or a unit test?

I'm not testing a single unit
and the code is an app, not a library.

[edit]
I've been rechecking it and I'm looking for an integration test.

error[E0433]: failed to resolve: use of undeclared crate or module `my_app`
 --> tests/test.rs:6:5
  |
6 | use my_app::shared::constants::command::SUDO;
  |     ^^^^^^^^^^^^^^^^^^^^^ use of undeclared crate or module `my_app`

For more information about this error, try `rustc --explain E0433`.
error: could not compile `my_app` (test "test") due to 1 previous error

What should main.rs look like?

Maybe you don't have a lib.rs? See below - I believe you need a library that is used by the binary, as well as by the integration tests. Nevermind, I see in the OP that you are adding a lib.rs. But perhaps the chapter below can help.

https://doc.rust-lang.org/book/ch11-03-test-organization.html#integration-tests-for-binary-crates

1 Like

The distinction between "unit" and "integration" is somewhat arbitrary. For the purposes of cargo, the distinction that matters is whether you want to test the internals of your crate, or whether you want to test it against its public interface.

Unit tests are part of the same crate and participate in the same intra-crate visibility rules as any other module; integration tests are compiled as separate crates and must use your crate's public interface.

4 Likes

Alright, so it's internal or external tests and I want internal ones,
so the test folder and files should go inside the src folder.

Created and it works!

./src/tests.rs

mod test;

./src/tests/test.rs

#[cfg(test)]
mod tests {
  use crate::shared::constants::command::SUDO;

  #[test]
  fn test_run() {
      let home_dir = format!("/home/user");
      let home_path = Path::new(home_dir);
  
      // Todo: run my_capp methods that create home_path
      assert_eq!(home_path.exists(), true)
      assert_eq!(SUDO, "sudo");
  }
}
1 Like