toxを使って複数バージョンのPythonでテストを実行する

複数のバージョンのPythonでテストを実行するときは、toxを使うと一括で実行してくれて便利。
tox 2.3.1 : Python Package Index

インストール

easy_installで入れてしまう。

$ sudo easy_install tox

Pythonは python2.5, python2.6, python2.7 のようなコマンドが実行可能であれば、それが使われる。

動かしてみる

toxはvirtualenvを作って、対象のモジュールをvirtualenv環境にインストールしてからテストを実行してくれる。
こんな感じのディレクトリ構成でファイルを用意した。

$ tree tox_hello/
tox_hello/
├── setup.py
├── tests.py
└── tox.ini
tests.py

足し算の結果を返すadd関数を定義して、それをテストするだけのモジュール。

# coding: utf-8
from unittest import TestCase


def add(a, b):
    return a + b


class AddTestCase(TestCase):
    def testInt(self):
        self.assertEqual(add(1, 1), 2)
        self.assertEqual(add(5, 10), 15)
        self.assertEqual(add(-10, 10), 0)

    def testStr(self):
        self.assertEqual(add("abc", "def"), "abcdef")
setup.py

virtualenv環境へインストールするためには、setup.pyが必要なので用意。

from setuptools import setup

setup(
  name="tox_hello",
)
tox.ini

toxの設定ファイル。
今回はテストランナーにnoseを使う。テスト対象のPythonのバージョンは、2.5, 2.6, 2.7, 3.2。

[tox]
envlist = py25,py26,py27,py32
[testenv]
deps =
  nose
commands = nosetests
実行結果

tox.iniを置いたディレクトリで、toxコマンドを実行する。

$ tox
GLOB sdist-make: /home/tokibito/sandbox/tox_hello/setup.py
py25 create: /home/tokibito/sandbox/tox_hello/.tox/py25
py25 installdeps: nose
py25 sdist-inst: /home/tokibito/sandbox/tox_hello/.tox/dist/tox_hello-0.0.0.zip
py25 runtests: commands[0]
..
----------------------------------------------------------------------
Ran 2 tests in 0.012s

OK
py26 create: /home/tokibito/sandbox/tox_hello/.tox/py26
py26 installdeps: nose
py26 sdist-inst: /home/tokibito/sandbox/tox_hello/.tox/dist/tox_hello-0.0.0.zip
py26 runtests: commands[0]
..
----------------------------------------------------------------------
Ran 2 tests in 0.015s

OK
py27 create: /home/tokibito/sandbox/tox_hello/.tox/py27
py27 installdeps: nose
py27 sdist-inst: /home/tokibito/sandbox/tox_hello/.tox/dist/tox_hello-0.0.0.zip
py27 runtests: commands[0]
..
----------------------------------------------------------------------
Ran 2 tests in 0.011s

OK
py32 create: /home/tokibito/sandbox/tox_hello/.tox/py32
py32 installdeps: nose
py32 sdist-inst: /home/tokibito/sandbox/tox_hello/.tox/dist/tox_hello-0.0.0.zip
py32 runtests: commands[0]
..
----------------------------------------------------------------------
Ran 2 tests in 0.019s

OK
___________________________________________ summary ___________________________________________
  py25: commands succeeded
  py26: commands succeeded
  py27: commands succeeded
  py32: commands succeeded
  congratulations :)