When I’m doing outside-in TDD (and that is basically whenever I’m coding) I often process things as a stack. I write an acceptance level test, run it. It fails (hopefully), so I write a lower level test, let’s say, a controller test. It fails. I might need go further and write a model unit test.
When I finish the inner TDD loop (say, unit on a model) I want to “pop the stack” and run the controller one, having that done, I want to run the acceptance test again. Often times the inner part of the loop takes long enough that you might forget what exactly what you were doing before, lose track of the files you had and ask your pair “what was the feature again?”.
This is a general problem and I think every editor can have a tool to solve this. I couldn’t find it for the editors I use on a daily basis (Vim, Sublime Text or RubyMine, depending on who I’m pairing with). So I got something that we use here at Pivotal and implemented my solution on top of it for Vim.
The solution we have here was created to solve yet another problem, how to run tests from Vim asynchronously, that means, without blocking your editor. Most development environments have this functionality and I think it’s quite useful specially when pairing.
There are several ways to accomplish it in Vim, and we have been doing this using a unix pipe thanks to my coworker and good friend, Andrew Bruce.
The reason why I like this setup very much for pairing is because it raises the visibility of the test results, I like them always on screen so both can see it all the time regardless of how fast you can visually parse it, it looks somewhat like this:
So you have you code in a window and your test results always visible. As a bonus, if you are on OS X and using iTerm2 you can
⌘ + Click a filename:line number to open the file in MacVim (Preferences -> Profiles -> Advanced, Open With Editor…, MacVim).
This is all very good and helps a lot. But I wanted a bit more, the first thing I noticed is that I kept wanting to run arbitrary commands that our “test_server” don’t support.
My fork of Andrew’s idea, vipe, is a more generic command pipe, that runs anything. With that I am able to send commands to the terminal and maybe map a key to it. For example
:nmap ,t :Vipe ruby <c-r>%<cr> for simply running a ruby script with
,t. To do that I removed all the ruby/rspec/rails specific functionality from the original version and moved that into my personal vim config.
And then I implemented my most wanted stack of commands in Vipe. Running a command will automatically push it into the stack, you can simply run
:VipePop and it will run the previous command, as simple as that. Similarly
:VipeRerun reruns the last command.
And that’s about it, Vipe is a command runner for vim that has a command stack and allow you to run any arbitrary command you want, I haven’t spend so much time perfecting and I think there is space for improvement. I hope you find it useful.