How to run multiple tests on subprojects in Rust?

Hi. I have an API server that I want to re-write to Rust & Actix-web. Since this project is rather large, I splice it up to several sub-projects (libraries). The main.rs acts as the root of the application.

Each of this library has its own test. I can use terminal and use cd command to each sub-project and run the test on it with cargo r

But it's kind a tedious for me, so my question is can I run test on all of them at once (ideally from the top / root project folder) ?

You want a workspace. This combines multiple Cargo packages so that you can run tests and such on all of them at once.

https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html

https://doc.rust-lang.org/cargo/reference/workspaces.html

Note that there are two ways to arrange a workspace: one with a root package (where your main currently is) and one with a “virtual manifest” where the top level isn't a package at all. I recommend the second option since it causes Cargo commands to operate on the whole workspace by default.

(Also, packages in a workspace are not usually put in the src directory, but at the top level or in a directory called crates sometimes.)

3 Likes

I tried. It's not that easy... while yes, I can compile and test them all at once, I have a security concern with workspaces

I asked about it here How to use Cargo package with Rust's workspace? and I just realized that you're the one who answered it.

Basically your solution at that time is to publicly publish my libraries to crates.io, and add the dependencies to it just like any other packages.

But this is not an ideal solution for me, not because I'm selfish but it's a private code, so I cannot publish them for everyone to see. So I work around that and just create another subproject inside.

What's the use case for cargo package here? Are you distributing the crates inside an organization or something?

I don't understand what your situation is, now.

  • If you have one package, then cargo test should automatically run all tests in it; no extra steps are required.

  • If you have multiple packages, then creating a workspace won't require you to publish anything.

Wait — you said

Each of this library has its own test. I can use terminal and use cd command to each sub-project and run the test on it with cargo r

If you're using cargo run and not cargo test, that sounds like your "tests" are not defined as cargo test targets, which is a problem because it means you can't run them all. But it also sounds like you have something odd going on, because cding within a package doesn't change anything.

Could you show what your project layout within those directories is? And what is in the Cargo.toml file(s)? I suspect that something non-standard is going on and we will need details to give good advice.

Sure, the sub project are all library I created with the command

cargo new <library_name> --lib

in a nutshell, I don't know how to integrate and structuring a bunch of smaller project into one.

The main cargo.toml:

[package]
name = "quik_3"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

# the main project depends on these library / sub_projects inside the src folder
api_handler = {path="src/api_handler", version="0.1.0"}
book_keeper = {path="src/book_keeper", version="0.1.0"}
company_manager = {path="src/company_manager", version="0.1.0"}
contact_book = {path="src/contact_book", version="0.1.0"}
transact_manager = {path="src/transact_manager", version="0.1.0"}
commons = {path="src/commons", version="0.1.0"}
inv_manager = {path="src/inv_manager", version="0.1.0"}
tata_tr = {path="src/tata_tr", version="0.1.0"}

# also dependencies outside from local src folder
env_logger = "0.9.0"
actix-easy-multipart = "2.1.1"
actix-web = "4.1.0"
serde = { version = "1.0.137", features = ["derive"] }

Okay, you have many packages. If you want to run tests on all of them, you need to create a workspace — see the links in my first post in this thread. Then you can run cargo test --workspace to run all tests.

1 Like

I distribute the cargo package for use inside a team, and also to split the workload into smaller project that can be tested individually

doesn't work :smiling_face_with_tear:. The only viable way top test is by cd src/<subproject_name> and then run cargo test

Usually subcrates are in folders at the top level (or in a folder structure of their own), not in folders inside src. I don't think it makes a huge difference but it is a bit odd to have subcrates in the src folder.

I experimented a bit with a similar folder structure and I think the problem is that cargo test is defaulting to just testing the top level crate.

Here's the structure I set up

Both crates have the autogenerated test from cargo new, though I tacked a 2 on to the subcrate's test for clarity

plain old cargo test:

% cargo test
    Finished test [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/lib.rs (~/Documents/Development/workspace-tests/target/debug/deps/workspace_tests-6cfa1fc2e4dd0df1)

running 1 test
test tests::it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests workspace-tests

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

But if I specify --workspace it runs both tests

cargo test --workspace
    Finished test [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/lib.rs (~/Documents/Development/workspace-tests/target/debug/deps/one-5e88b38a86147d5d)

running 1 test
test tests::it_works2 ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running unittests src/lib.rs (~/Documents/Development/workspace-tests/target/debug/deps/workspace_tests-6cfa1fc2e4dd0df1)

running 1 test
test tests::it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests one

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

   Doc-tests workspace-tests

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

1 Like