1.pytestをインストールする
pytest には Python 3.6、3.7、3.8、3.9 または PyPy3 が必要です。
(1) コマンドラインで次のコマンドを実行します。
pip install -U pytest
結果:
(2) 正しいバージョンがインストールされているかどうかを確認します。
(venv) E:\auto_pytest>pytest --version
pytest 6.2.3
2. 最初のテストを作成する
関数とテストを含む test_sample.py という新しいファイルを作成します。
#!/usr/bin/env python
# encoding: utf-8
"""
@author: 九九的金金子
@file: test_sample.py.py
@time: 2021/4/12 11:56
"""
# content of test_sample.py
def func(x):
return x + 1
def test_answer():
assert func(3) == 5
実行と結果:
(venv) E:\auto_pytest>pytest test_sample.py
========================================================================== test session starts ==========================================================================
platform win32 -- Python 3.7.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: E:\auto_pytest
plugins: allure-pytest-2.8.32
collected 1 item
test_sample.py F [100%]
=============================================================================== FAILURES ================================================================================
______________________________________________________________________________ test_answer ______________________________________________________________________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
test_sample.py:14: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_sample.py::test_answer - assert 4 == 5
=========================================================================== 1 failed in 0.13s ===========================================================================
[100%] は、すべてのテスト ケースの実行の全体的な進行状況を指します。func(3) が 5 を返さないため、完了すると pytest は失敗レポートを表示します。
注:
Assert ステートメントを使用して、テストの期待を検証できます。アサート式の中間値は、pytest の高度なアサーション内でインテリジェントにレポートされます。
3. 複数のテストを実行する
pytest は、現在のディレクトリとそのサブディレクトリにあるtest_.pyまたは_test.py形式のすべてのファイルを実行します。より一般的には、標準のテスト検出ルールに従います。
例外が発生したことをアサートする
raises ヘルパーを使用して、一部のコードが例外を発生したことをアサートします。
#!/usr/bin/env python
# encoding: utf-8
"""
@author: 九九的金金子
@file: test_sysexit.py
@time: 2021/4/12 13:49
"""
# content of test_sysexit.py
import pytest
def f():
raise SystemExit(1)
def test_mytest():
with pytest.raises(SystemExit):
f()
実行と結果:
(venv) E:\auto_pytest>pytest -q test_sysexit.py
. [100%]
1 passed in 0.12s
q/ --quiet フラグにより、この例と次の例では出力が短くなります。
4. 複数のテストを 1 つのクラスにグループ化する
複数のテストを開発したら、それらを 1 つのクラスにグループ化することができます。pytest を使用すると、複数のテストを含むクラスを簡単に作成できます。
#!/usr/bin/env python
# encoding: utf-8
"""
@author: 九九的金金子
@file: test_class.py
@time: 2021/4/12 13:52
"""
# content of test_class.py
class TestClass:
def test_one(self):
x = "this"
assert "h" in x
def test_two(self):
x = "hello"
assert hasattr(x, "check")
pytest は、Python テスト検出規則に従うすべてのテストを検出するため、test_ というプレフィックスが付いた 2 つの関数を検出します。何かをサブクラス化する必要はありませんが、必ずクラスの先頭に Test を付けるようにしてください。そうしないと、クラスはスキップされます。ファイル名を渡すだけでモジュールを実行できます:
結果を実行します:
(venv) E:\auto_pytest>pytest -q test_class.py
.F [100%]
=============================================================================== FAILURES ================================================================================
__________________________________________________________________________ TestClass.test_two ___________________________________________________________________________
self = <test_class.TestClass object at 0x000001934888F248>
def test_two(self):
x = "hello"
> assert hasattr(x, "check")
E AssertionError: assert False
E + where False = hasattr('hello', 'check')
test_class.py:16: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_class.py::TestClass::test_two - AssertionError: assert False
1 failed, 1 passed in 0.12s
最初のテストは成功しましたが、2 番目のテストは失敗しました。アサーション内の中間値を簡単に確認できるため、失敗した理由を理解できます。
クラス内でテストをグループ化すると、次の理由で有益です。
- 試験機関
- その特定のクラスのテストのフィクスチャのみを共有します
- クラスレベルでタグを適用し、翻訳ページ内のすべてのテストに暗黙的にタグを適用します。
テストをクラスにグループ化する場合、各テストにはクラスの一意のインスタンスがあることに注意することが重要です。すべてのテストで同じクラス インスタンスを共有することは、テストの分離にとって非常に悪く、不十分なテスト手法を促進します。これについては次のように概説されます。
#!/usr/bin/env python
# encoding: utf-8
"""
@author: 九九的金金子
@file: test_class_demo.py
@time: 2021/4/12 13:56
"""
# content of test_class_demo.py
class TestClassDemoInstance:
def test_one(self):
assert 0
def test_two(self):
assert 0
実行と結果:
(venv) E:\auto_pytest>pytest -k TestClassDemoInstance -q
FF [100%]
=============================================================================== FAILURES ================================================================================
____________________________________________________________________ TestClassDemoInstance.test_one _____________________________________________________________________
self = <test_class_demo.TestClassDemoInstance object at 0x00000228F08E27C8>
def test_one(self):
> assert 0
E assert 0
test_class_demo.py:11: AssertionError
____________________________________________________________________ TestClassDemoInstance.test_two _____________________________________________________________________
self = <test_class_demo.TestClassDemoInstance object at 0x00000228F08DE748>
def test_two(self):
> assert 0
E assert 0
test_class_demo.py:14: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_class_demo.py::TestClassDemoInstance::test_one - assert 0
FAILED test_class_demo.py::TestClassDemoInstance::test_two - assert 0
2 failed, 5 deselected in 0.19s
クラス レベルで追加された属性はクラス属性であるため、テスト間で共有されることに注意してください。
5. 機能テスト用に固有の一時ディレクトリを要求します。
pytest は、固有の一時ディレクトリなどの任意のリソースを要求するための組み込みフィクスチャ/関数引数を提供します。
#!/usr/bin/env python
# encoding: utf-8
"""
@author: 九九的金金子
@file: test_tmp_path.py
@time: 2021/4/12 13:58
"""
# content of test_tmp_path.py
def test_needsfiles(tmp_path):
print(tmp_path)
assert 0
テスト関数のシグネチャに tmp_path という名前をリストすると、pytest はテスト関数呼び出しを実行する前にフィクスチャ ファクトリを検索して呼び出し、リソースを作成します。テストを実行する前に、pytest はテストの各呼び出し (
実行と結果) に固有の一時ディレクトリを作成します。
(venv) E:\auto_pytest>pytest -q test_tmp_path.py
F [100%]
=============================================================================== FAILURES ================================================================================
____________________________________________________________________________ test_needsfiles ____________________________________________________________________________
tmp_path = WindowsPath('C:/Users/01399256/AppData/Local/Temp/pytest-of-01399256/pytest-2/test_needsfiles0')
def test_needsfiles(tmp_path):
print(tmp_path)
> assert 0
E assert 0
test_tmp_path.py:11: AssertionError
------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------
C:\Users\01399256\AppData\Local\Temp\pytest-of-01399256\pytest-2\test_needsfiles0
======================================================================== short test summary info ========================================================================
FAILED test_tmp_path.py::test_needsfiles - assert 0
1 failed in 0.19s
一時ディレクトリの処理の詳細については、「一時ディレクトリとファイル」を参照してください。
そのコマンドにどのタイプの組み込み pytest フィクスチャが存在するかを確認します。
pytest --fixtures # shows builtin and custom fixtures
-v オプションを追加しない限り、このコマンドは _ で始まるフィクスチャを省略することに注意してください。