注釈
ここで答えが見つからない場合は 連絡先 から助けを求めてください。
理由の一部は歴史的なもので、それ以外は実用上のものです。 py.test は、複数の開発者向けユーティリティを提供する py パッケージの一部として使われていました。それは全て py.<TAB> で始まり、このように <TAB> を補完する優れた機能を提供しています。 pip install pycmd でインストールしたら、別々のパッケージからそういったツールを確認できます。最近になって、コマンドラインツールは pytest と呼んでいますが、昔からの多くの人たちが古い名前になじんでいて “pytest” という名前は別ツールに思えます。そのため、我々は py.test という名前を使い続けることに決めました。
py.test と nose は、Python テストを書いて実行するのに同じ基本理念をもっています。 nose は、もともと py.test が 0.8 リリースのときに py.test のクローンとして作成されました。pytest 2.0 は unittest のテストスイートを実行できるようになったのが主な改善点であることに注目してください。そして、多くの Django や Twisted のテストスイートを変更せずに実行できます。
2007年頃 (バージョン 0.8)、py.test はあまりにも多くの “魔法” を使っていると主張する人たちがいました。未使用なコード、非推奨、複雑なコードを削除することで部分的には解消されました。今日では、py.test は確かに Python 向けの最も小さく普遍的でカスタマイズ可能なテストフレームワークの1つです。但し py.test は、まだ多くのメタプログラミングテクニックを使っていて、Python 初心者がそのソースを読めるものではありません。
2番目の “魔法” の課題は、間違いなく assert 文のデバッグ機能です。テストモジュールが読み込まれると、py.test は assert 文のソースコードを書き換えます。書き換えられた assert 文が失敗したとき、そのエラーメッセージは、オリジナルの assert 文より分かりやすいものです。py.test にも別のデバッグ手法があります。書き換えが失敗することにより assert 文が失敗したとき、py.test はテストが失敗したときに中間値を表示するためにその式を再解釈します。この別のデバッグ手法は書き換えが行われなかったという警告で悩まされます。その式が副作用 (とにかく触らないのが良い!) をもつなら、中間値は同じにならない可能性があります。それは再解釈するインタープリターを混乱させ、初期のエラーを分かり難くします (これも発生したらコマンドラインで表示される) 。 py.test --assertmode=off により、全てのアサーションデバッグを無効にできます。
シンプルなアプリケーション向けや、nose か unittest スタイルの経験がある人たちにとっては、おそらく 拡張された xUnit スタイルのセットアップフィクスチャ を使う方が自然に感じるはずです。しかし、巨大なテストスイート向けでは、パラメーターテストや funcargs を使った複雑なテストリソースのセットアップの方がもっと自然に感じるかもしれません。さらに言うと、funcargs は高度なテストサポートコード (例えば monkeypatch, tmpdir, capture, funcargs) を書くのに最適です。というのは、そのサポートコードは class/module/function スコープを管理する setup/teardown 関数を登録できるからです。
我々は 設定より規約 を好み、より柔軟に抽象的な仕組みを許容するのに意味があるとは思いませんでした。さらに、ソースコード内で pytest_funcarg__MYARG を検索できるのは便利で、 MYARG という関数の引数に対する全てのファクトリー関数を戸惑いなく探せます。
ファクトリー関数が yield できない概念上の理由が2つあります:
両方の課題を解決するために pytest_generate_tests フックを使い、 パラメーター化の仕組みにあったものを選択して 実装してください。
Windows 上の multiprocess パッケージは、pickle 化することでサブプロセスをインスタンス化し、暗黙的にたくさんのローカルモジュールを再インポートします。残念ながら、setuptools 0.6.11 が作成したコマンドラインスクリプトは if __name__=='__main__' による保護がありません。これにより、実行中のテストがプロセスをインスタンス化するときに無限再帰を引き起こします。
良い解決策は、setuptools の置き換えとして distribute をインストールする ことです。その後に pytest を再インストールします。別の方法では、setuptools が作成したスクリプトに if __name__ == '__main__' を追加して修正します。もしくは、この内容を含む “pytest.py” スクリプトを作成して、そのスクリプトを実行します:
import pytest
if __name__ == '__main__':
pytest.main()