pytest を使用してテストを実行しています。
module で定義されたすべてのテストの前に前提条件を実行したいpytest.fixture
ので、前提条件関数を作成し、 withで装飾して scope = "module"
、モジュール内のすべてのテストに対して 1 回だけ実行されるようにしました。test_target
この前提条件は、テスト用に準備するために取得する別のフィクスチャを使用します。それに加えて、テスト関数自体も同様に使用され、yaml ファイルからロードされた
test_target
別の関数も使用されました。テストするデバイスは常に、テストするターゲットの情報を含むdevices.yaml ファイルで定義されているため、yaml ファイルからロードされたデータでと をパラメータ化しています。test_param
test_target
test_param
私が得ている問題は、モジュールスコープで実行するように定義している前提条件が関数スコープで実行されていることです。
辞書を test_target に直接割り当ててパラメーター化すると、前提条件が期待どおりに動作することに気付きました (モジュール スコープ) が、デバイス情報をハードコーディングする必要があります。
私は何を間違っていますか?おそらく、この前提条件を実行するための別の回避策がありますか? 私はjsonでそれを試しましたが、yamlとまったく同じ動作をしています
を使用した私のセットアップ:
- WSL-Ubuntu 20.04
- パイソン3.9
- pytest 6.2.5
私のサンプルテストツリー:
.
├── station.json
├── station.yaml
└── test
├── conftest.py
├── test_1.py
└── test_2.py
1 directory, 5 files
station.yaml
my_station:
target1: 12345
param1: 67890
station.json
{
"my_station": {
"target1": 12345,
"param1": 67890
}
}
conftest.py
import time
import json
import pytest
import yaml
def pytest_generate_tests(metafunc):
devices_file = "station.yaml"
sut_name = "my_station"
with open(devices_file,"r") as file:
setups = yaml.safe_load(file)
# setups = json.load(file)
# setups = {
# "my_station": {
# "target1": 12345,
# "param1": 67890,
# }
# }
sut = setups.get(sut_name)
if not sut:
pytest.exit(
f"{sut_name} configuration not found\
on file {devices_file}"
)
targets = [device for device in sut if device.startswith("target")]
params = [device for device in sut if device.startswith("param")]
if "test_target" in metafunc.fixturenames:
metafunc.parametrize("test_target", targets, scope="module")
if "test_param" in metafunc.fixturenames:
metafunc.parametrize("test_param", params, scope="module")
@pytest.fixture(scope="module")
def precondition1(test_target):
print(f"\nStart precondition1 \nSave current status of test target {test_target}")
yield
time.sleep(0.1)
print(f"\nStop precondition1 \nRestore original status of test target {test_target}")
test1.py
def test_foo(test_target, test_param, precondition1):
assert True
def test_boo(test_target, test_param, precondition1):
assert True
def test_bar(test_target, test_param, precondition1):
assert True
def test_mar(test_target, test_param, precondition1):
assert True
test2.py
def test_nah(test_target, precondition1):
assert True
def test_duh(test_target, precondition1):
assert True
def test_bla(test_target, precondition1):
assert True
この出力を取得する前に、コードのようにテストを実行すると
❯ pytest -s -v
======================================================================================================================== test session starts ========================================================================================================================
platform linux -- Python 3.9.5, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- /bin/python3.9
cachedir: .pytest_cache
rootdir: /home/pedro/repos/pytest_fixture
collected 7 items
test/test_1.py::test_foo[target1-param1]
Start precondition1
Save current status of test target target1
PASSED
test/test_1.py::test_boo[target1-param1]
Stop precondition1
Restore original status of test target target1
Start precondition1
Save current status of test target target1
PASSED
test/test_1.py::test_bar[target1-param1]
Stop precondition1
Restore original status of test target target1
Start precondition1
Save current status of test target target1
PASSED
test/test_1.py::test_mar[target1-param1]
Stop precondition1
Restore original status of test target target1
Start precondition1
Save current status of test target target1
PASSED
Stop precondition1
Restore original status of test target target1
test/test_2.py::test_nah[target1]
Start precondition1
Save current status of test target target1
PASSED
test/test_2.py::test_duh[target1]
Stop precondition1
Restore original status of test target target1
Start precondition1
Save current status of test target target1
PASSED
test/test_2.py::test_bla[target1]
Stop precondition1
Restore original status of test target target1
Start precondition1
Save current status of test target target1
PASSED
Stop precondition1
Restore original status of test target target1
========================================================================================================================= 7 passed in 0.74s =========================================================================================================================
一方、ロードされた値を直接割り当ててテストを実行すると(conftest.pyの行のコメントを外します)
setups = {
"my_station": {
"target1": 12345,
"param1": 67890,
}
}
次の出力が得られます。
❯ pytest -s -v
======================================================================================================================== test session starts ========================================================================================================================
platform linux -- Python 3.9.5, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- /bin/python3.9
cachedir: .pytest_cache
rootdir: /home/pedro/repos/pytest_fixture
collected 7 items
test/test_1.py::test_foo[target1-param1]
Start precondition1
Save current status of test target target1
PASSED
test/test_1.py::test_boo[target1-param1] PASSED
test/test_1.py::test_bar[target1-param1] PASSED
test/test_1.py::test_mar[target1-param1] PASSED
Stop precondition1
Restore original status of test target target1
test/test_2.py::test_nah[target1]
Start precondition1
Save current status of test target target1
PASSED
test/test_2.py::test_duh[target1] PASSED
test/test_2.py::test_bla[target1] PASSED
Stop precondition1
Restore original status of test target target1
========================================================================================================================= 7 passed in 0.26s =========================================================================================================================