Introduction
If you ever used VS Code to edit Rust source code, you might already know you can launch just the test you care about.
But I love too much Vim to convert to VSCode. And yes, I know there is a Vim plugin but these emulation plugins are never complete and I always end up using vim shortcuts that doesn’t exist in the plugin. It annoys me.[1]
However, there is a bunch of nice things in VSCode like running the test you want, without running the entire suite test.
Selecting tests with cargo
First of all, let see how to run a test and only the tests you want.
If you have a lib.rs
with the following test.
#[cfg(test)]
mod tests {
use super::*;
mod addition_tests {
use super::*;
#[test]
fn add_works() {
assert_eq!(1 + 1, 2);
}
#[test]
#[should_panic]
fn add_panics() {
assert_ne!(1 + 1, 2);
}
}
}
Then you can run the add_work()
test function with
cargo test --lib -- --exact tests::addition_tests::add_works
Or run all the tests in this file with
cargo test --lib -- tests::addition_tests
And it works similarly for integration tests.
cargo test --test addition
will run all the tests in tests/addition.rs
and
cargo test --test addition -- --exact add_works
will only run the add_works()
function in tests/addition.rs
.
Let’s do it in vim
The algorithm is relatively simple. We start from the position of the cursor and try to deduce what test the user want to launch. If the cursor is inside a test function, let’s launch only this function. If the cursor is in a file that contains test, let’s launch all the tests of this file, etc.
Here is a simplified algorithm. First, we iterate over the blocks { … }
going from the narrower block containing the cursor, to the larger block
containing the cursor. During this iteration, we identify the block of the test
function (function annotated with #[test]
) if there is one, and all the
wrapping modules. Then we can iterate on the file path to deduce the rest of
the modules.
From the file path, we can also deduce if this is an integration test or not.
This will help to choose between --lib
or --test
options.
You can find the code in my vim script here.
Conclusion
Now, you have a nice function that you can map to a shortcut. I use
F6
.
noremap <F6> <Esc>:call <SID>rust_execute_test()<Enter>
I will add an additional comment because we forget too often about that, vim
documentation is awesome. Most of my problems in writing this script was solved
through documentation. The only drawback of the documentation is to find the
right section. [2]