The Test.vim plugin gives you four simple commands that run tests in different ways.
TestSuite command runs all the tests in the whole project.
TestFile command runs all tests in the current file.
TestNearest command runs the test that is closest to the cursor, which is useful for when you have multiple failing tests in the same file, and you just want to concentrate on a single one.
And last but not least,
TestLast repeats the previous test command.
This is the most commonly used command, and it’s what makes this workflow so fast.
I’ve hooked these four commands up to leader combos in my
vimrc file so that I can run them more quickly.
nnoremap <leader>ta :TestSuite<cr> nnoremap <leader>tf :TestFile<cr> nnoremap <leader>tn :TestNearest<cr> nnoremap <leader>tt :TestLast<cr>
To demonstrate the workflow, I’m going to take a test file from exercism.io and write the implementation to make the tests pass.
I start by running
TestFile, which gives me an error because the implementation file doesn’t exist.
I create the implementation file in a split to the right, and run
TestLast, which will repeat the
TestFile command, and now we can see 11 failing tests.
I just want to focus on a single test right now, so I go back to the test file, put the cursor inside the first test, and run
The output now shows a single failing test.
The test failed because the
Binary class doesn’t exist, so I start by making an empty class definition, and then run
Now the test is failing because the
initialize method is missing.
I write the
initialize method, without a body for now, and run
It’s complaining that the
to_decimal method is missing, so I write that too, and now we get an actual assertion failure instead of an exception.
This is failing because the methods have no body yet, so I’ll fill in the methods now.
TestLast again, and I see that the test passes.
Now that I have one test passing, I run
TestFile, and see that all the test are passing except for two.
One failure is due to the Exercism bookkeeping thing being missing, so I’ll implement that.
TestLast, and now there is just one failing test.
I write the implementation to make that test pass, run
TestLast again, and now all the tests are passing.
With all the tests passing, I can do some refactoring.
Every time I make a change, I run
TestLast again to make sure I haven’t broken anything.
When I’m happy with the refactoring, and all the tests are still passing, I’m finished.
That concludes one TDD red-green-refactor cycle.
As you can see this workflow has a very tight feedback loop.
I write a little bit of code, run
TestLast, and repeat.
I can make
TestLast run a single test, a whole test file, or all the tests in the project, depending on what is most appropriate for the situation.
In closing, if you’re a vim user, definitely try out the Test.vim plugin. It works straight out of the box, with no configuration. I was using Minitest in this demonstration, but it handles RSpec as well, and it also supports 13 different programming languages, which means that if you’re switching between languages frequently, you can still use the same testing workflow.