Fandom

Vim Tips Wiki

Integration with PyUnit testing framework

Redirected from VimTip280

1,624pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

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.

Doing

: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 alltests.py script.

:setlocal makeprg=./alltests.py

Here is an example alltests.py:

#!/usr/bin/env python2
import unittest
import sys
sys.path.append('unittests')

modules_to_test = (
'fooTest',
'barTest',
'bazTest',
)

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

if __name__ == '__main__':
  unittest.main(defaultTest='suite')

Here is an alternative alltests.py:

#!/usr/bin/env python
#
# This script is based on the one found at http://vim.wikia.com/wiki/VimTip280
# but has been generalised. It searches the current working directory for
# *_test.py (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/alltests.py

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():
    sys.path.append(os.curdir)
    modules_to_test = find_all_test_files()
    print 'Testing', ', '.join(modules_to_test)
    alltests = unittest.TestSuite()
    for module in map(__import__, modules_to_test):
	alltests.addTest(unittest.findTestCases(module))
    return alltests

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

        sys.stderr.write("Exception:\n")
        ex = traceback.format_exception_only(exceptionType, exceptionValue)
        for line in ex:
            sys.stderr.write(line)

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

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/alltests.py

ReferencesEdit

CommentsEdit

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)

Also on Fandom

Random Wiki