pytest, mock, testfixture!

(´・ω・`)はい。こんにちは。パーフェクトPythonも無事?発売されて一安心なaodagです。 まあ、なんかテスト関連でよくいろいろ言ってる気がするのですが、最近ツールを変えたので、覚書を。 これまで:

  • nose
  • unittest2
  • mock

という組み合わせでした。 unittest2の豊富なassert系メソッドとnoseの豊富なプラグインってところです。 テストケース自体はunittest2で書いて、noseのテストランナーを使うと。   が、最近もうこの2つはpytestに変えました。 だいたいいつも使ってるようなのは、pytestでまかなえるし、pytest-covがあれば十分かな。 追加で使うツールとして、mockは続投、testfixtureが便利な気がするので、使い始めてます。 それぞれのツールの使い方はだいたいそこらへんのマニュアルとか見てくれればいいと思うので、pytestでどのようなことをしてるかってのを。 zopeやpyramid界隈では、テスト用のダミーやフィクスチャ(データフィクスチャじゃないよ。まったく某フレームワークのせいでフィクスチャっていうとデータのことばかり...)を testing というモジュールにまとめておくのが慣例です。 で、pyramidにもtestingモジュールがあり、 testing.setUp, testing.tearDownというのが、テスト用のコンポーネントレジストリを初期化するフィクスチャです。 pytest的なフィクスチャにしてみます。

@pytest.fixture

def config(request):

    from pyramid import testing
    config = testing.setUp()

    def fin():
        testing.tearDown()

    request.addfinalizer(fin)

    return config
 

pytest.fixtureデコレータでフィクスチャの登録をします。 なかでやってるのは、testing.setUpの呼び出しと、testing.tearDownをテスト後に呼び出すための設定です。 requestがそういうフックを設定するためのオブジェクトです。 このフィクスチャを使うには、テストケースの引数にconfigという名前をつけます。 pytestが、フィクスチャの名前と同じ引数のところに自動でフィクスチャの戻り値を渡してくれます。

from .testing import config

def test_it(config):

    config.include('test.under.the.module')
 

楽ですね。 testfixtureは、汎用的なフィクスチャがそろっています。 日付やログ、ファイル出力、ファイルシステムの操作など、ユニットテストでよくあるめんどうな部分をカバーしてくれてるので、便利に使えるようになりたいものです。 テストツールのセットアップ テストツールが増えてくるとそれをインストールするのも簡単にすませたいところです。 テストツールようのrequirementsを用意しといてもいいのですが、 setup.pyに書く場所があるので、そっちを使います。

setup(name="...",
      ....
      tests_require=["pytest", "mock", "testfixtures"],
      ....
     )
 

このように書いておくと、 python setup.py test とすれば、現在のディレクトリにインストールされます。 うざいですね。 extras_requireを使うと、現在の環境にインストールできます。

tests_require = ["pytest", "mock", "testfixtures"]

setup(name="test.under.the.package",
      ....
      tests_require=tests_require,
      extras_require={"testing": tests_require},
      ....
      )
 
このようにしておくと、  python setup.py develop easy_install test.under.the.package[testing] などのコマンドでテストツールまで、インストールできます。
長くてめんどうなので、 setup.cfg にエイリアスを作ります。
[aliases]
dev = develop easy_install test.under.the.package[testing]
 
最近のpip (1.2以上のバージョン)も extrasをサポートしています。
pip を使う場合は pip install -e .[testing] というコマンドで、ほぼ同じようになります。
これらのツールはpython3対応もしてるので、長い付き合いができそうです。