Trdelnik Logo # Trdelník Ackee Blockchain Discord invitation developed by [Ackee Blockchain](https://ackeeblockchain.com) [![Crates.io](https://img.shields.io/crates/v/trdelnik-cli?label=CLI)](https://crates.io/crates/trdelnik-cli) [![Crates.io](https://img.shields.io/crates/v/trdelnik-test?label=Test)](https://crates.io/crates/trdelnik-test) [![Crates.io](https://img.shields.io/crates/v/trdelnik-client?label=Client)](https://crates.io/crates/trdelnik-client) [![Crates.io](https://img.shields.io/crates/v/trdelnik-explorer?label=Explorer)](https://crates.io/crates/trdelnik-explorer)
[![lint](https://github.com/Ackee-Blockchain/trdelnik/actions/workflows/lint.yml/badge.svg)](https://github.com/Ackee-Blockchain/trdelnik/actions/workflows/lint.yml) [![test-examples-turnstile](https://github.com/Ackee-Blockchain/trdelnik/actions/workflows/test-examples-turnstile.yml/badge.svg)](https://github.com/Ackee-Blockchain/trdelnik/actions/workflows/test-examples-turnstile.yml)

Trdelník is Rust based testing framework providing several convenient developer tools for testing Solana programs written in Anchor.

Trdelnik Demo

Dependencies

Installation

```shell cargo install trdelnik-cli

or the specific version

cargo install --version trdelnik-cli ```

Usage

```shell

navigate to your project root directory

trdelnik init

it will generate .program_client and trdelnik-tests directories with all the necessary files

trdelnik test

want more?

trdelnik --help ```

How to write tests?

``rust // <my_project>/trdelnik-tests/tests/test.rs // TODO: do not forget to add all necessary dependencies to the generatedtrdelnik-tests/Cargo.toml` use programclient::myinstruction; use trdelnikclient::*; use myprogram;

[throws]

[fixture]

async fn initfixture() -> Fixture { // create a test fixture let mut fixture = Fixture { client: Client::new(systemkeypair(0)), // make sure your program is using a correct program ID program: programkeypair(1), state: keypair(42), }; // deploy a tested program fixture.deploy().await?; // call instruction init myinstruction::initialize( &fixture.client, fixture.state.pubkey(), fixture.client.payer().pubkey(), System::id(), Some(fixture.state.clone()), ).await?; fixture }

[trdelnik_test]

async fn testhappypath(#[future] initfixture: Result) { let fixture = initfixture.await?; // call the instruction myinstruction::dosomething( &fixture.client, "dummystring".toowned(), fixture.state.pubkey(), None, ).await?; // check the test result let state = fixture.getstate().await?; asserteq!(state.something_changed, "yes"); } ```

Make sure your program is using a correct program ID in the derive_id!(...) macro and inside Anchor.toml. If not, obtain the public key of a key pair you're using and replace it in these two places. To get the program ID of a key pair (key pair's public key) the trdelnik key-pair command can be used. For example $ trdelnik key-pair program 7 will print information about the key pair received from program_keypair(7).

Instructions with custom structures

```rust pub struct MyStruct { amount: u64, }

// ...

pub fn my_instruction(ctx: Context, data: MyStruct) { /* ... */ } ```

```rust // .program_client/src/lib.rs

// DO NOT EDIT - automatically generated file pub mod myprograminstruction { use trdelnikclient::*; use myprogram::MyStruct; // add this import

// ... } ```

Skipping tests

```rust

[trdelnik_test]

[ignore]

async fn test() {} ```

Testing programs with associated token accounts

```toml

/trdelnik-tests/Cargo.toml

import the correct versions manually

anchor-spl = "0.24.2" spl-associated-token-account = "1.0.3" ```

```rust // /trdelnik-tests/tests/test.rs use anchorspl::token::Token; use splassociatedtokenaccount;

async fn initfixture() -> Fixture { // ... let account = keypair(1); let mint = keypair(2); // constructs a token mint client .createtokenmint(&mint, mint.pubkey(), None, 0) .await?; // constructs associated token account let tokenaccount = client .createassociatedtokenaccount(&account, mint.pubkey()) .await?; let associatedtokenprogram = splassociatedtokenaccount::id(); // derives the associated token account address for the given wallet and mint let associatedtokenaddress = splassociatedtokenaccount::getassociatedtokenaddress(&account.pubkey(), mint); Fixture { // ... token_program: Token::id(), } } ```

Supported versions

| Trdelnik CLI | Anchor | Solana | |--------------|:---------:|---------:| | latest | ~0.25.* | >=1.10 | | v0.2.0 | ~0.24.* | >=1.9 |

Configuration

The configuration variables can be edited in the Trdelnik.toml file that'll be generated in the root of the project.

| Name | Default value | Description | |----------------------------------|---------------|-----------------------------------------------------------------------------| | test.validator_startup_timeout | 10 000 | Time to wait for the solana-test-validator in milliseconds before failure |

Roadmap

Awards

Marinade Community Prize - winner of the Marinade grant for the 2022 Solana Riptide Hackathon.

Contribution

Thank you for your interest in contributing to Trdelník! Please see the CONTRIBUTING.md to learn how.

License

This project is licensed under the MIT license.

University and investment partners