単純なイベントエミッターの実装をテストすることで、pytestの使用方法を学んでいます。
基本的にはこんな感じ
class EventEmitter():
def __init__(self):
...
def subscribe(self, event_map):
# adds listeners to provided in event_map events
def emit(self, event, *args):
# emits event with given args
便宜上、テストで使用するListener
クラスを作成しました
class Listener():
def __init__(self):
...
def operation(self):
# actual listener
現在、テストは次のように見えます
@pytest.fixture
def event():
ee = EventEmitter()
lstr = Listener()
ee.subscribe({"event" : [lstr.operation]})
return lstr, ee
def test_emitter(event):
lstr = event[0]
ee = event[1]
ee.emit("event")
assert lstr.result == 7 # for example
イベントエミッターをテストするには、イベントの伝播後にリスナーの内部状態が変化したかどうかを確認する必要があります。したがって、2つのオブジェクトが必要ですが、これを行うにはもっと良い方法があるのではないかと思います(おそらく、1つではなく2つのフィクスチャを使用する)。これは私にはちょっと醜いように見えるからです。
うん!この場合、おそらく2つの器具が必要になります。
@pytest.yield_fixture
を次のように試すことができます:
@pytest.yield_fixture
def event():
...
yield <event_properties>
@pytest.yield_fixture
def listener(event):
...
yield <listener_properties>
通常、tuples
を回避してコードを美化するために、collections.namedtuple
を使用して、それらをクラスとして1つのユニットに結合し直すことができます。
import collections
EventListener = collections.namedtuple('EventListener', 'event listener')
次に、フィクスチャを変更します。
@pytest.fixture
def event_listener():
e = EventListener(EventEmitter(), Listener())
e.event.subscribe({'event' : [e.listener.operation]})
return e
次に、テストを変更します。
def test_emitter(event_listener):
event_listener.event.emit('event')
assert event_listener.listener.result == 7
Python iterable unpacking という機能を変数に使用する必要があります。
def test_emitter(event):
lstr, ee = event # unpacking
ee.emit("event")
assert lstr.result == 7
基本的に、event[0]
をlstr
に割り当て、event[1]
をee
に割り当てます。この機能の使用は、インデックスの使用を回避するための非常に洗練された方法です。
複数のテストでフィクスチャを使用する予定で、すべてのテストですべての値が必要なわけではない場合、次のように使用することに興味がなければ、反復可能要素の一部の要素を破棄することもできます。
l = ['a', 'b', 'c', 'd']
a, b, c, d = l # unpacking all elements
a, _, c, d = l # discarding b
a, _, _, d = l # python 2: discard b and c
a, *_, d = l # python 3: discard b and c
a, _, _, _ = l # python2: discard, b, c and d
a, *_ = l # python3: discard b, c, and d
理論的には、文字通り値を破棄しているわけではありませんが、 Pythonの場合_
、いわゆる「私は気にしない」は、特定の値を無視するために使用されます。
簡単に タプルフィクスチャを2つの独立したフィクスチャに分割する の余裕がない場合は、-で説明されているように、pytest-cases
プラグインを使用して、タプルまたはリストフィクスチャを他のフィクスチャに「アンパック」できます。 この回答 。
あなたの例では、次のようになります。
from pytest_cases import pytest_fixture_plus
@pytest_fixture_plus(unpack_into="lstr,ee")
def event():
ee = EventEmitter()
lstr = Listener()
ee.subscribe({"event" : [lstr.operation]})
return lstr, ee
def test_emitter(lstr, ee):
ee.emit("event")
assert lstr.result == 7 # for example