With Woke 2.0, we introduced an updated version of our Python-based development and testing framework.
Let’s look closely and find out how it differs from other Python-based testing frameworks and what are Woke’s advantages.
Woke testing framework builds on the so-called
pytypes. These are automatically generated Python files representing Solidity contracts, structs, enums, etc. in the Python world. Files in the
pytypes directory are organized in such a way so that it reflected the directory structure of the original Solidity sources.
pytypes not only provide auto-completion and type hints support but also work as standalone objects that do not need any external files (Solidity source files, for example). All necessary information is included in
pytypes for a project in a current working directory, one can you the
woke init pytypes command. An optional
--watch option launches the
pytypes generator in watch mode. Solidity source files are watched for changes and
pytypes are automatically re-generated.
Woke testing framework was inspired by Brownie, thus the way it interacts with the contracts may be familiar to Brownie users. However, as Woke learned from Brownie’s mistakes, there are some crucial differences and improvements.
Getting started with Woke
First, a contract must be imported from
pytypes. Importing contracts from different namespaces (modules) is essential as it helps to avoid name clashes.
Like Brownie, Woke testing framework uses pytest to collect tests and offer various features like fixtures. From the very beginning, Woke testing framework was designed to support multichain (cross-chain) testing. Still, it is expected that most of the tests will perform single-chain testing. There is a
default_chain global object that should be used for single-chain testing. It can be imported from the
woke.testing module along with all other objects one may need.
default_chain can be either connected to an already running dev chain or launch a new dev chain.
With the default configuration, Woke uses Anvil as the development chain. Anvil is a part of the Foundry project. It is highly recommended to keep Anvil up-to-date: Woke development team co-operates with Anvil developers to ensure a seamless experience when writing tests.
default_chain connected to a dev chain, it is easy to deploy the first contract using Woke testing framework.
Main differences from Brownie
The previous example shows another difference from Brownie. Any additional data that modify a transaction or call are passed using keyword arguments instead of a dictionary. By default,
view Solidity functions (including public state variable getters) are called using
eth_call, i.e. a transaction is not sent. The
request_type keyword can override this.
Another significant difference from Brownie is that
pytypes function calls that send a transaction return the function return value instead of a transaction object. Setting
return_tx=True in a function call or even generating
return_tx implicitly set:
woke init pytypes --return-tx can override this.
This example may show yet another advantage of Woke testing framework: it was designed to be very fast. There are a few things to keep in mind in order to achieve maximum performance:
- Anvil should be used whenever possible
- Transaction events should be accessed only when necessary; working with
tx.eventsmay be slow in some cases
- Transactions should be mainly sent from pre-generated accounts (
default_chain.accounts); sending a transaction from any other account is possible but at the expense of poorer performance.
pytypes, transaction events can be worked with using native Python objects, dataclasses.
events is the property of a transaction object received either by setting
return_tx=True or by defining
tx_callback is automatically called for transactions that do not have
return_tx=True set. User-defined errors are also generated in the form of dataclasses. Additionally, there are two internal types of errors:
Panic(int). Errors are automatically raised as exceptions with
return_tx set to
False. There are helper context managers,
may_revert, to make handling exceptions easier.
The mentioned above covers the key differences between Woke and Brownie. Be sure to check out our documentation and follow our Twitter to stay updated.