Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 0 additions & 97 deletions docs/development/testing/e2e.md

This file was deleted.

163 changes: 163 additions & 0 deletions docs/development/testing/node-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
---
title: Node Tests
hide_title: true
slug: /contract-testing/node-tests
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

![Testing Title Picture](/img/title/testing1.svg)

# Node Tests

Node tests use `#[ink_e2e::test]` and deploy your contract to an actual Substrate node.

The examples below are based on the [assets-precompile-node contract](https://github.com/use-ink/ink/blob/master/integration-tests/public/assets-precompile-node/lib.rs).

## Basic Structure

```rust
#[cfg(all(test, feature = "e2e-tests"))]
mod e2e_tests {
use super::*;
use ink_e2e::{ContractsBackend, alice, bob, assert_ok, assert_noop, assert_last_event};

type E2EResult<T> = Result<T, Box<dyn std::error::Error>>;

#[ink_e2e::test]
async fn it_works(mut client: Client) -> E2EResult<()> {
let contract = client
.instantiate("my-contract", &alice(), &mut MyContractRef::new(42))
.submit()
.await?;

let call_builder = contract.call_builder::<MyContract>();
let result = client.call(&alice(), &call_builder.get()).dry_run().await?;
assert_eq!(result.return_value(), 42);

Ok(())
}
}
```

## Running Tests

<Tabs>
<TabItem value="pop" label="Pop CLI" default>
```bash
pop test --e2e
```
</TabItem>
<TabItem value="cargo" label="cargo">
Requires `ink-node`. See [Setup](../../../getting-started/setup.md#ink-node) for installation.

```bash
export CONTRACTS_NODE=ink-node
cargo test --features e2e-tests
```
</TabItem>
</Tabs>

## Asserting State

```rust
#[ink_e2e::test]
async fn balance_of_works(mut client: Client) -> E2EResult<()> {
let asset_id: u32 = 1;

client.create(&asset_id, &alice(), 1u128).await?;
client.mint_into(&asset_id, &alice(), &alice(), 1000u128).await?;

let contract = client
.instantiate("assets_precompile_node", &alice(), &mut AssetHubPrecompileRef::new(asset_id))
.submit()
.await?;

let call_builder = contract.call_builder::<AssetHubPrecompile>();
let result = client.call(&alice(), &call_builder.balance_of(alice().address())).dry_run().await?;
assert_eq!(result.return_value(), U256::from(1000));

Ok(())
}
```

## Testing Success

```rust
use ink_e2e::assert_ok;

#[ink_e2e::test]
async fn transfer_works(mut client: Client) -> E2EResult<()> {
// Setup asset and contract...

let result = client
.call(&alice(), &call_builder.transfer(bob_addr, 1_000.into()))
.submit()
.await?;

assert_ok!(&result);

Ok(())
}
```

## Testing Errors

```rust
use ink_e2e::assert_noop;

#[ink_e2e::test]
async fn transfer_fails_insufficient_balance(mut client: Client) -> E2EResult<()> {
// Setup asset and contract...

let result = client
.call(&alice(), &call_builder.transfer(bob_addr, 1_000_000.into()))
.submit()
.await?;

assert_noop!(result, "BalanceLow");

Ok(())
}
```

## Testing Events

```rust
use ink_e2e::assert_last_event;

#[ink_e2e::test]
async fn transfer_emits_event(mut client: Client) -> E2EResult<()> {
// Setup and transfer...

let result = client
.call(&alice(), &call_builder.transfer(bob_addr, 1_000.into()))
.submit()
.await?;

assert_ok!(&result);
assert_last_event!(
&result,
Transfer {
from: contract.addr,
to: bob_addr,
value: 1_000.into()
}
);

Ok(())
}
```

## Cargo.toml

```toml
[dev-dependencies]
ink_e2e = { version = "6.0.0-beta.1" }

[features]
default = ["std"]
std = ["ink/std"]
e2e-tests = []
```
75 changes: 65 additions & 10 deletions docs/development/testing/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,72 @@ hide_title: true
slug: /contract-testing/overview
---

![Testing1 Title Picture](/img/title/testing1.svg)
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Testing Strategies
![Testing Title Picture](/img/title/testing1.svg)

ink! supports three different stages of testing: unit, integration
and end-to-end tests. In this chapter we'll explain what the purpose
of each stage is about and how to use it.
# Testing Overview

![ink! Testing Strategies](/img/testing.png)
ink! provides three testing approaches for different needs:

Generally you can think of those three types of testing as a pyramid
with the top being the most elaborate test. The End-to-End (E2E)
tests at the top will test the lower layers of the pyramid as part
of them.
| Aspect | Unit Tests | Runtime Tests | Node Tests |
|--------|-----------|---------------|------------|
| **Runtime interaction** | ❌ No | ✅ Yes | ✅ Yes |
| **Cross-contract calls** | ❌ No | ✅ Yes | ✅ Yes |
| **Precompiles** | ❌ No | ✅ Yes | ✅ Yes |
| **Initial compile** | Fast | Slow (compiles runtime) | Medium |
| **Test execution** | Fastest | Fast (after first compile) | Slower (node spawn) |
| **Rust analyzer** | ✅ Contract | ✅ Contract + Runtime | ✅ Contract |
| **External dependencies** | None | None | Requires ink-node |

## When to Use What

```
Does your contract need to interact with the runtime?
(cross-contract calls, precompiles, pallet access)

├── NO → Use Unit Tests
│ Fast, simple, test your contract logic in isolation
└── YES → Use Runtime Tests or Node Tests
├── Need to debug runtime internals?
│ └── Use Runtime Tests
│ Rust analyzer works on runtime code too
├── Want fast iteration after first compile?
│ └── Use Runtime Tests
│ First compile is slow, then very fast
├── Want quick setup, no runtime compilation?
│ └── Use Node Tests
│ Spawns ink-node, slightly slower per test
└── Need the most production-like environment?
└── Use Node Tests
Tests against a real node, closest to mainnet
```

## Running Tests

<Tabs>
<TabItem value="pop" label="Pop CLI" default>
```bash
# Unit tests
pop test

# E2E tests (runtime and node)
pop test --e2e
```
</TabItem>
<TabItem value="cargo" label="cargo">
```bash
# Unit tests
cargo test

# E2E tests (runtime and node)
cargo test --features e2e-tests
```
</TabItem>
</Tabs>
Loading
Loading