expect_events
class ExpectedEventData(TypedDict):
    name: str
    data: NotRequired[list[int] | dict[str, Any] | None]
    from_address: NotRequired[int]
ExpectedEventName = str
ExpectedEvent = ExpectedEventData | ExpectedEventName
def expect_events(*expected_events: ExpectedEvent) -> None: ...
Compares expected events with events in the Starknet state. You can use this cheatcode to test whether a contract emits specified events. Protostar compares events after a test case is completed. Therefore, you can use this cheatcode in any place within a test case.
Protostar also checks the order of emitted events.
%lang starknet
@event
func foobar(number: felt) {
}
func emit_foobar{syscall_ptr: felt*, range_check_ptr}(number: felt) {
    foobar.emit(number);
    return ();
}
@contract_interface
namespace BasicContract {
    func increase_balance() {
    }
}
// ----------------------------------------------
@external
func test_expect_events_are_in_declared_order{syscall_ptr: felt*, range_check_ptr}() {
    %{ expect_events({"name": "foobar", "data": [21]}, {"name": "foobar", "data": [37]}) %}
    emit_foobar(21);
    emit_foobar(37);
    return ();
}
@external
func test_expect_event_by_contract_address{syscall_ptr: felt*, range_check_ptr}() {
    alloc_locals;
    local contract_address: felt;
    %{
        ids.contract_address = deploy_contract("./src/commands/test/examples/cheats/expect_events/basic_contract.cairo").contract_address
        expect_events({"name": "balance_increased", "from_address": ids.contract_address})
    %}
    BasicContract.increase_balance(contract_address=contract_address);
    return ();
}
tip
You can provide "data" as a dictionary to leverage data transformer - see example below
Emitting a complex structured event, and expecting it in tests using data transformer
%lang starknet
struct InnerStruct {
    b : felt,
    c : felt,
}
struct DeeplyNestedStruct {
    inner : InnerStruct,
    a : felt,
}
@event
func structured_event(structure: DeeplyNestedStruct, side_arg: felt) {
}
func emit_structured_event{syscall_ptr: felt*, range_check_ptr}(number: felt) {
    let inner_struct = InnerStruct(
        b=number + 1,
        c=number + 2,
    );
    let deeply_nested = DeeplyNestedStruct(
        inner=inner_struct,
        a=number,
    );
    structure_event.emit(deeply_nested);
    return ();
}
// ----------------------------------------------
@external
func test_emitting_struct_with_data_transformer{syscall_ptr: felt*, range_check_ptr}() {
    %{
        expect_events({
            "name": "structured_event",
            "data": {
                "structure": {
                    "a": 21,
                    "inner": {
                        "b": 22,
                        "c": 23,
                    }
                },
                "side_arg": 37
            }
        })
    %}
    emit_structured_event(21, 37);
    return ();
}