Vim Tips Wiki
Tip 280 Printable Monobook Previous Next

created 2002 · complexity intermediate · author Stefan Roemer, Max Ischenko · version 6.2

Vim has a wonderful ability to integrate with external tools, like compilers, make, ctags, etc. That's one of the reasons we love it. PyUnit can be seen as a "compiler" for Python code.


:compiler pyunit

will set the 'errorformat' option for PyUnit, enabling Vim to parse a unittest test runner's output and to enter quickfix mode.

To run all your unit tests at once, using Vim's :make command, you'll need to set the 'makeprg' option and provide a test runner. This is often done using an script.

:setlocal makeprg=./

Here is an example

#!/usr/bin/env python2
import unittest
import sys

modules_to_test = (

def suite():
  alltests = unittest.TestSuite()
  for module in map(__import__, modules_to_test):
  return alltests

if __name__ == '__main__':

Here is an alternative

#!/usr/bin/env python
# This script is based on the one found at
# but has been generalised. It searches the current working directory for
# * (good) or test_*.py (bad) files and runs each of the unit-tests
# found within.
# When run from within Vim as its 'makeprg' with the correct 'errorformat' set
# (by setting ":compiler pyunit"), any failure will deliver your cursor to the
# line that breaks the unit tests.
# Place this file somewhere where it can be run, such as ${HOME}/bin/

import unittest, sys, os, re, traceback

def find_all_test_files():
    t_py_re = re.compile('^(test_.*|.*_test)\.py$')
    is_test = lambda filename: t_py_re.match(filename)
    drop_dot_py = lambda filename: filename[:-3]
    return [drop_dot_py(module) for module in
            filter(is_test, os.listdir(os.getcwd()))]

def suite():
    modules_to_test = find_all_test_files()
    print 'Testing', ', '.join(modules_to_test)
    alltests = unittest.TestSuite()
    for module in map(__import__, modules_to_test):
    return alltests

if __name__ == '__main__':
    except SystemExit:
        # we reverse the Exception/Traceback printout order so vim's
        # quickfix works properly
        exceptionType, exceptionValue, exceptionTraceback = sys.exc_info()

        ex = traceback.format_exception_only(exceptionType, exceptionValue)
        for line in ex:

        sys.stderr.write("\nTraceback (most recent call first):\n")
        tb = traceback.format_tb(exceptionTraceback)
        for line in reversed(tb):

To have Vim automatically use these settings for all Python files, add the following to ~/.vim/after/ftplugin/python.vim ($HOME\vimfiles\after\ftplugin\python.vim on Windows)

" Additions to Vim's filetype plugin for Python, to set up PyUnit as
" the 'compiler' for Python files.

" Set the errorformat.
compiler pyunit

" Set 'makeprg': this allows you to call :make on any .py file and
" run all of the unit tests in the current working directory.
" Ensure you have this file.
setlocal makeprg=${HOME}/bin/



The following abbreviations are useful when writing unit tests in Python.

iabbr <buffer> sa_ self.assert_
iabbr <buffer> sae self.assertEquals
iabbr <buffer> saf self.assertFalse
iabbr <buffer> san self.assertNotEquals
iabbr <buffer> sar self.assertRaises
iabbr <buffer> sat self.assertTrue

I don't think the abbreviations belong in this tip. They are not on topic and may be distracting. (Spiiph 10:48, 3 August 2009 (UTC))

There are no tips really suitable for holding the iabbr info; following are slightly plausible candidates. Meanwhile, I have moved the abbreviations to the comments section where they are less intrusive. JohnBeckett 03:20, 4 August 2009 (UTC)