Transcript

In this short video I want to demonstrate a fast TDD workflow using the Test.vim plugin by Janko Marohnić (I hope I pronounced that properly).

The Test.vim plugin gives you four simple commands that run tests in different ways. The TestSuite command runs all the tests in the whole project. The TestFile command runs all tests in the current file. The 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 TestNearest . 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 TestLast . Now the test is failing because the initialize method is missing. I write the initialize method, without a body for now, and run TestLast again. 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. I run 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. I run 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.