pythonのテスト環境についてちょっと調べてみたのでまとめ
あわせて読みたい:
Contents
py.test vs nose vs unittest
だいたい人気のあるtesting frameworkはこの3つ。
testing framework
|
説明
|
---|---|
py.test | テストの自動探索/実行機能などがあり、簡単に使える。黒魔術に頼っていたためにnoseというクローンが作られ、人気の座を奪われた。 |
nose | 一番人気。python組み込みのunittest上に構築されているのも特徴。 |
unittest | Pythonの組込みモジュール。xUnit型。unittest 2ではテストの自動探索機能などが追加されている。 |
歴史的には
- 2000年: Kent BeckがJUnitをリリース
- 2001年: xUnitの1つとしてunittestがPython 2.1に組み込まれる。
- ???: py.test リリース。この時点でテストの自動探索/実行機能を装備していたかは不明。
- ???: py.test 0.8の時点でメタプログラミングだらけの「黒魔術」が原因?でnoseがcloneとして作られる。noseが最初からunittest上に作られていたかは不明。
- 2010年: unittest2 リリース。自動探索機能を搭載。
など、各々便利な機能を取り込んで発展してきたもよう。
- 活発に使われていること
- 出自が「コードの汚さへの反発」というポジティブな目的があること
- 組込みモジュールのunittestのテストを実行できるという柔軟さ
から、noseを使うのが良いと思う。
リポジトリ内での使い方
Jupyter notebookのレンダリングを行う公式webアプリであるnbviewerでの使い方が綺麗( https://github.com/jupyter/nbviewer/blob/master/tasks.py )。
travis-ci + invoke (Pythonのタスクランナー) + nose
という構成。
ここでは、
- travis ciを使用(.travis.ymlを実行)
- .travis.ymlでinvokeを使用して環境のセットアップやtestコマンドを外部ファイル化(tasks.py)
- pipのパッケージはrequirements.txtとして外部ファイル化。
- テストに必要なパッケージのインストールはrequirements-dev.txtとして分離。
- invokeでtasks.pyを実行
- tasks.pyの内部でnosetestsでテストを実行
という流れで自動テストを実行している。(なお、jupyter notebookのレポジトリではtravis ciだけでなくcircle ciも使っている)
このような構成とすることで、以下のメリットが得られる:
- invokeでテストの一括実行が出来るようにすることで、ciサービス(ローカルでの手動実行も含め)間の差異を環境設定ファイルだけにとどめている。
- テストだけでない環境構築等のタスクもinvokeとしてモジュール化できる。
構成サンプル
project_root
|- app # アプリのディレクトリ
|- tests
|- test_*.py # テストコード
|- .travis.yml
|- tasks.py
|- requirements.txt
|- requirements-dev.txt
|- Dockerfileなど
- .travis.yml
language: python
python:
- '2.7'
- '3.3'
- '3.4'
before_install:
# テストに必要な環境を整える
- sudo apt-get update
- pip install -r requirements-dev.txt
install:
# アプリケーションに必要なパッケージをインストール
- pip install -r requirements.txt
script:
# テストの実行
- invoke test
- tasks.py
import invoke
@invoke.task
def test(ctx):
ctx.run("nosetests -v")
- requirements-dev.txt
invoke
nose
- app/tests/test_example.py (例)
#!/usr/bin/env python
def test_numbers_3_4():
assert 3 * 4 == 12
参考
- Python, Django 界隈の単体テスト事情(unittest / nose / django-nose): http://akiyoko.hatenablog.jp/entry/2015/01/01/212712
- Python用のユニットテストツールまとめ: http://coreblog.org/ats/python-testing-tools-taxonomy/
- 課題と質問 (Py.test Document): http://pytest.org/latest-ja/faq.html
- Ten Years Of Test Driven Development: http://c2.com/cgi/wiki?TenYearsOfTestDrivenDevelopment
- Python の新ユニットテストフレームワーク (or unittest2): http://surgo.jp/2011/12/python-or-unittest2.html
コメント