標準 (Python) テストディスカバリーの変更¶
テスト収集中のパスの無視¶
コマンドラインの --ignore=path オプションを渡すことで、特定のテストディレクトリやモジュールを簡単に無視できます。 pytest は複数の --ignore オプションを許可します。 例:
tests/
|-- example
| |-- test_example_01.py
| |-- test_example_02.py
| '-- test_example_03.py
|-- foobar
| |-- test_foobar_01.py
| |-- test_foobar_02.py
| '-- test_foobar_03.py
'-- hello
'-- world
|-- test_world_01.py
|-- test_world_02.py
'-- test_world_03.py
例えば、pytest を --ignore=tests/foobar/test_foobar_03.py --ignore=tests/hello/ として実行すると、指定されたパターンに一致しないテストモジュールのみが収集されます。
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-5.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile:
collected 5 items
tests/example/test_example_01.py . [ 20%]
tests/example/test_example_02.py . [ 40%]
tests/example/test_example_03.py . [ 60%]
tests/foobar/test_foobar_01.py . [ 80%]
tests/foobar/test_foobar_02.py . [100%]
========================= 5 passed in 0.02 seconds =========================
--ignore-glob オプションを使用すると、Unixシェルスタイルのワイルドカードに基づいてテストファイルのパスを無視できます。 例えば、_01.py で終わるテストモジュールを除外するには、pytest を --ignore-glob='*_01.py' で実行します。
テスト収集中にテストを除外する¶
--deselect=item オプションを渡すことで、個別にテストを除外できます。 例えば、tests/foobar/test_foobar_01.py に test_a と test_b が含まれている場合、pytest を --deselect tests/foobar/test_foobar_01.py::test_a で実行すると、tests/foobar/test_foobar_01.py::test_a 以外の全テストが実行されます。 複数の --deselect オプションも使用可能です。
コマンドラインで指定された重複パスの保持¶
pytest のデフォルト動作は、コマンドラインで指定された重複パスを無視することです。 例:
pytest path_a path_a
...
collected 1 item
...
テストを一度だけ収集する
重複したテストを収集するには、コマンドラインで --keep-duplicates オプションを使用します。 例:
pytest --keep-duplicates path_a path_a
...
collected 2 items
...
コレクタはディレクトリ単位で動作するため、同じテストファイルを2回指定すると、--keep-duplicates が指定されていなくても2回収集されます。 例:
pytest test_a.py test_a.py
...
collected 2 items
...
ディレクトリ再帰処理の変更¶
プロジェクトルートの ini ファイル(例: pytest.ini)で norecursedirs オプションを設定できます。
# content of pytest.ini
[pytest]
norecursedirs = .svn _build tmp*
これにより、pytest は通常の Subversion や sphinx-build ディレクトリ、または tmp で始まるディレクトリの再帰処理を行いません。
命名規則の変更¶
設定ファイル 内の python_files、python_classes、python_functions を設定することで、異なる命名規則を構成できます。 例:
# content of pytest.ini
# Example 1: have pytest look for "check" instead of "test"
[pytest]
python_files = check_*.py
python_classes = Check
python_functions = *_check
これにより、pytest は check_* .py に一致するファイル、クラスの Check プレフィックス、ならびに *_check に一致する関数・メソッド内のテストを探します。 例えば、
# content of check_myapp.py
class CheckMyApp:
def simple_check(self):
pass
def complex_check(self):
pass
テスト収集は次のようになります:
$ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 2 items
<Dir pythoncollection.rst-206>
<Module check_myapp.py>
<Class CheckMyApp>
<Function simple_check>
<Function complex_check>
======================== 2 tests collected in 0.12s ========================
パターン同士の間にスペースを入れることで、複数のグロブパターンを指定できます:
# Example 2: have pytest look for files with "test" and "example"
# content of pytest.ini
[pytest]
python_files = test_*.py example_*.py
注釈
python_functions および python_classes オプションは、unittest.TestCase のテスト検出には影響しません。 pytest はテストケースメソッドの検出を unittest に委譲しているためです。
コマンドライン引数を Python パッケージとして解釈する¶
--pyargs オプションを使用すると、引数を Python パッケージ名として解釈し、対応するファイルシステムパスを導出してテストを実行します。 例えば、unittest2 をインストールしている場合、次のように入力できます:
pytest --pyargs unittest2.test.test_skipping -q
これにより対象のテストモジュールが実行されます。 他のオプション同様、ini ファイルの addopts オプションでこの設定を恒久的に変更できます:
# content of pytest.ini
[pytest]
addopts = --pyargs
pytest NAME とシンプルに実行すると、NAME がインポート可能なパッケージ/モジュールとして存在するか確認し、存在しなければファイルシステムパスとして扱われます。
収集内容の確認¶
テストを実行せずに収集ツリーを確認することも可能です:
. $ pytest --collect-only pythoncollection.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 3 items
<Dir pythoncollection.rst-206>
<Dir CWD>
<Module pythoncollection.py>
<Function test_function>
<Class TestClass>
<Function test_method>
<Function test_anothermethod>
======================== 3 tests collected in 0.12s ========================
テスト収集のカスタマイズ¶
すべての Python ファイルからテストを検出するように pytest に指示できます:
# content of pytest.ini
[pytest]
python_files = *.py
しかし、多くのプロジェクトにはインポートしたくない setup.py が存在します。 また、特定の Python バージョンでのみインポート可能なファイルもあるため、そのような場合は conftest.py ファイルに無視するファイルを動的に定義できます:
# content of conftest.py
import sys
collect_ignore = ["setup.py"]
if sys.version_info[0] > 2:
collect_ignore.append("pkg/module_py2.py")
そして、このようなモジュールファイルがある場合:
# content of pkg/module_py2.py
def test_only_on_python2():
try:
assert 0
except Exception, e:
pass
さらに、このような setup.py のダミーファイルがある場合:
# content of setup.py
0 / 0 # will raise exception if imported
Python 2 インタプリタで実行すると、1つのテストが収集され、setup.py ファイルは除外されます:
#$ pytest --collect-only
====== test session starts ======
platform linux2 -- Python 2.7.10, pytest-2.9.1, py-1.4.31, pluggy-0.3.1
rootdir: $REGENDOC_TMPDIR, inifile: pytest.ini
collected 1 items
<Module 'pkg/module_py2.py'>
<Function 'test_only_on_python2'>
====== 1 tests found in 0.04 seconds ======
Python 3 インタプリタで実行すると、1つのテストとともに setup.py ファイルも除外されます:
$ pytest --collect-only
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
rootdir: /home/sweet/project
configfile: pytest.ini
collected 0 items
======================= no tests collected in 0.12s ========================
また、Unix シェルスタイルのワイルドカードによるパターンを collect_ignore_glob に追加することで、ファイルを無視することも可能です。
以下の例では、Python 3 インタプリタ実行時に、conftest.py が setup.py および *_py2.py で終わるすべてのファイルを無視します。
# content of conftest.py
import sys
collect_ignore = ["setup.py"]
if sys.version_info[0] > 2:
collect_ignore_glob = ["*_py2.py"]
Pytest 2.6 以降、ユーザーは __test__ 属性を False に設定することで、Test で始まるクラスを検出しないようにできます。
# Will not be discovered as a test
class TestClass:
__test__ = False