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.