Hi!
If your charm deals with deferred events, custom events, and charm libs that in turn emit their own custom events, it can be hard to unit-test the resulting control flow. In these situations it can be useful to verify that, as a result of a given Juju event triggering, a specific chain of deferred and custom events is emitted on the charm. In Scenario tests, the output state, black-box as it is, gives little insight into how exactly it was obtained.
Scenario has just merged a little addition to its toolbox: capture_events
, a context manager some of you may already be familiar with (it’s been ripped off of harness-extensions).
scenario.capture_events
allows you to open a peephole in the otherwise pretty black State-box and intercept any events emitted by the framework while triggering an event on it.
What this looks like in practice:
from ops.charm import StartEvent
from scenario import Event, State
from charm import MyCharm, MyCustomEvent # Any custom event types
def test_my_event():
# capture any events of these types:
captured: List[CharmBase]
with capture_events(StartEvent, MyCustomEvent) as captured:
State().trigger("start", MyCharm, meta=MyCharm.META)
#
assert len(captured) == 2
e1, e2 = captured
assert isinstance(e2, MyCustomEvent)
assert e2.custom_attr == 'foo'
Read more about it here.