I have been looking for a good way to run Cucumber tests from inside of vim without having to switch to a terminal window and enter the cucumber command. My first solution was to add a couple of key maps to my .vimrc file:
map c :!cucumber -r features % map C :!cucumber
I use a comma as my leader. (set in the .vimrc file with)
let mapleader = ","
So by entering ,c while in command mode, vim fires off the cucumber command against the file that is in the current buffer (the one I’m working on) and ,C runs cucumber against the current working directory. This works okay, but it isn’t a perfect solution. Some of the problems are:
- The vim session freezes until the tests finish
- When I exit the command window I lose all of the output from running the tests
- With MacVim I lose color in the terminal
None of these are that big of a deal, but they do make it feel clunky.
Then I came across this post from Larry Marburger over the weekend that talks about setting vim up to send Cucumber commands to a screen session. He references a blog post by Jonathan Palardy that goes in to some good detail about how to get everything setup for this to work. Using these two posts as a reference I started experimenting, and I think I’ve come up with a pretty cool work flow.
These directions require Screen in order to work. I’m using MacVim, but if you are on a Linux machine you can replace mvim with gvim.
First off you need slime.vim. Move this to your ~/.vim/plugins/ directory.
Next, add this to your bash alias file:
function svim { local dir=`pwd`; mvim; screen -S slime; cd $dir; }
This creates a new shell function that:
- gets your current directory
- opens MacVim
- starts screen with a session named slime
- cd the new screen session back to the original directory you started from
Next we need to add 2 lines to our ~/.screenrc file:
termcapinfo xterm* ti@:te@ shelltitle 'w0'
Now we have some default Screen parameters that we can reference from our Vim session and we can setup some keyboard maps to make things easier:
.vimrc file
map <leader>t :call Send_to_Screen("cucumber -r features " . expand("%") . "\n")<CR>|
map <leader>T :call Send_to_Screen("cucumber" . "\n")<CR>|
The first one allows me to type ,t to run cucumber on the .features file I currently have open. The second sets up ,T to run cucumber on the entire project. Both send the command to a remote Screen session and Vim goes right back to what you were doing. By sending the commands to a remote screen this deals with all three of the problems that I mentioned earlier.
- You don’t have to wait for the tests to finish running before being able to move on to the next task.
- The output continues to be displayed in the terminal window while you work through any problems.
- The colors are displayed properly.
So what does the work flow look like with this setup?
- Open a terminal
- cd to the project directory
- Type svim
- Start working on a features file in mvim or gvim
- Type ,t to execute the scenarios from the current file
- Check output on terminal window (This works great if you have two monitors so that you don’t have to command/control tab to the terminal window)
- Type ,T if you want to execute all scenarios for the project
That’s it.