Scenario: def and async def

The decorator declares a scenario; the function form selects the execution mode.

since 0.1.0-rc.1since 0.3.0

Methods

EntrySignatureAvailable sinceAPI 3
casecase(identifier, *, timeout_s=20, labels=(), contracts=())0.1.0-rc.1def or async def
testtest(identifier, *, timeout_s=20, labels=(), contracts=())0.3.0as case

API 3 changes (0.5.0)

def keeps the synchronous form. Use async def when the target must run without stopping.

Recommended

A synchronous scenario for configuration and branches, an asynchronous one for a live window with halt in finally.

from stm32_gdbtest import case

@case("HW_BOOT", timeout_s=30, labels=("boot",))
def boot(t):
    t.reach("main")
    t.check("SystemCoreClock", t.read("SystemCoreClock"), 16_000_000)

@case("HW_LIVE", timeout_s=20)
async def live(t):
    await t.reach("app_loop")
    t.resume(sync=False)
    try:
        waited = await t.wait(timeout=0.2)
        t.check("still running", waited["outcome"], "timeout")
    finally:
        await t.halt(timeout=2)

Avoid

Navigation without await in async def: the next target operation is refused. Do not convert a working def to async without a reason.

@case("HW_LIVE")
async def live(t):
    t.reach("app_loop")      # no await
    t.resume(sync=False)     # refused: unawaited_operation

The fragments show refused or discouraged patterns, not a working recipe.

Fragments for a scenario body; firmware symbols are illustrative.

All groupsNavigation →