Concept
What is a scenario?
Let's take a moment to consider what an interaction with a blockchain might entail.
The primary way to alter the blockchain state is by sending transactions. Additionally, we may need to query some contracts in between sending these transactions, or even directly query the blockchain state, such as account balances. We can refer to these individual actions as "steps." In a simulated environment, we require at least one additional step: initializing the sandbox.
Multiple steps combined together form a scenario.
A scenario represents any form of interaction with a blockchain, comprised of one or more steps. These interactions can take various forms:
- Real interactions that have occurred on a live blockchain, forming a historical record.
- Programmed interactions intended for execution in the future.
- Simulated interactions, utilizing actual blockchain data.
- Simulated interactions that employ absurd or unrealistic data.
In essence, the nature of these steps, whether they are real or imaginary, is less important than their adherence to blockchain rules. Due to their broad applicability, it is natural to view all blockchain interactions and black-box tests as scenarios.
Scenario formats
The concept of a scenario is not limited to a specific technology or programming language.
Historically, scenarios started as JSON-based tests. However, manually crafting extensive JSON scenarios can be inconvenient and unproductive. To address this, we introduced a similar syntax in Rust. With the development of the interactor framework, we found that scenarios could naturally model real interactions.
ℹ️ Today, we believe that the JSON scenario format is best suited for interoperability and replays, rather than creating tests manually. |
There are several ways to automatically generate scenario JSON files, and we encourage developers to move away from manual JSON scenario creation. |
The primary advantage of the JSON format is its language-agnostic nature, making it compatible with any of our backends.
Scenarios as tests
Scenarios also incorporate syntax for verifying transaction outputs and blockchain states. Consequently, each scenario effectively functions as a test, with any failed checks leading to a test failure.
🚨 They are always black-box tests. They emulate actual blockchain interactions, without the ability to inspect contracts or access their private functions. |
Typed vs. untyped scenarios
At the blockchain level, transaction data is essentially untyped. Arguments, storage, logs, and more lack explicit types in the blockchain. Developers add types when writing contracts to enhance safety and prevent errors.
This implies that scenarios in their most general form are also untyped, a characteristic that aligns well with JSON, which is mostly untyped.
However, working exclusively with untyped and unannotated data can become cumbersome for developers. There are two approaches to overcome this:
- Utilizing a typed variant of scenarios, as seen in Rust.
- Employing a specialized language to present values more clearly to developers.
These are known as scenario value expressions, which assist in conveying numbers, addresses, and even more complex data in a more comprehensible manner. It's important to note that this doesn't introduce type checks; it's purely a cosmetic enhancement. You can find more details about the format of scenario value expressions here and here.