Zest is a code coverage CLI tool for Solana programs. Zest is built by LimeChain, a blockchain development and consulting firm founded in 2017. The development of the tool is supported by a grant from the Solana Foundation.
cargo install --git https://github.com/LimeChain/zest zest --force# Move into the target project
cd ./examples/setter/anchor
# This will run coverage for the example using the `instrument-coverage` strategy without `branch` info
zest coverage
# Path to the target project can also be specified using the `--path` option
zest coverage --path ./examples/setter/anchor
# Configuration options can also be read from a (TOML) config file (`zest-coverage.toml` by default)
cat <<TOML > my_zest_config.toml
path = "./examples/setter/anchor"
branch = true
# contract_style = "anchor"
# tests = ["integration"]
# output_types = ["lcov", "html"]
TOML
# Which would run with
# `coverage_strategy` being `instrument-coverage` (Default)
# `path` being `./examples/setter/anchor/` (from config file)
# `branch` being `false` (CLI override)
zest coverage --config ./my_zest_config.toml --branch falseNote
Check zest --help and zest coverage --help for more info
Note
More info on the different strategies can be found here
Currently, zest only supports testing programs, written in Rust, with tests written in Rust (usually using solana-program-test, as opposed to the classic Typescript tests), which do not depend on the cargo-{build,test}-sbf toolchain. A.K.A if cargo test works for you (not cargo test-sbf), then zest will too
Here's a small list of publicly available Solana programs that we've tested if they work with zest or not:
Works on:
How to make sure zest works for your program:
-
Make sure you're using a Rust framework (solana-program-test or similar, like liteSVM) for your testing purposes
-
Make sure your tests are runnable by just
cargo testThis is done by supplying your program's
processor(theprocess_instructionfunction) directly when adding it to the test validatorlet mut validator = ProgramTest::default(); validator.add_program( "counter_solana_native", counter_solana_native::ID, processor!(counter_solana_native::process_instruction), );
That requirement is incompatible with
shankframework, since it puts a type constraint on theprocessorfunction.
Note
That happens because of the context function from ShankContext, seen in their example (the 'a lifetime), which breaks the compatibility (and thus makes it testable only in sbf mode).
Note
Branch coverage can be enabled with the --branch flag but it requires a recent enough version of the nightly compiler to work.
It is also only supported when using the instrument-coverage coverage strategy (default).
There isn't yet a version of the compiler that both supports `branch` coverage and `solana-program` compilation
- To support the
rustccoverage-optionssetting (tellingrustchow to gather coverage information), we need a recent version of the compiler (this (seen in1.78.0) for simple branch coverage and this (seen in1.79.0) for advancedmcdcbranch coverage) - Our solana programs transitively depend on
ahash:solana-program v1.18.1(latest) ->borsh v0.9.3->hashbrown v0.11.2->ahash v0.7.7 - Unfortunately, since
Rustremoved support for thestdsimdfeature here (seen in1.78.0),ahash v0.7.7breaks - This is fixed in
ahash v0.8.0, but we cannot directly update the version used bysolana-program.- We can try to use
Cargo patchesto force the version ofahashbut they do not work for transitive dependencies (only for top-level ones, i.e. the ones in ourCargo.tomls)
- We can try to use
- The last version of the
Rustcompiler from before the removal ofstdsimdisnightly-2024-02-04, but it does not yet include support for-Z coverage-options(introduced roughly a month later)
Possible long-term solutions:
- The
solanaecosystem moves to a newer version of theRustcompiler Have no details about such intentions, haven't researched, will probably not be soon Cargo patchesstart working for transitive dependencies Unlikely, since it would be a nontrivial task to select the exact dependencies you want to patch
TLDR: we either chose to support branch coverage or the ability to compile solana programs (IMO the second is a far more important requirement)
For feedback, feature requests or general inquiries, please reach out to [email protected]
