Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Moonwall #315

Merged
merged 11 commits into from
Jan 28, 2025
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"label": "moonwall_config",
"defaultTestTimeout": 30000,
"environments": [
{
"name": "default_env",
"testFileDir": ["tests/"],
"foundation": {
"type": "dev"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div id="termynal" data-termynal>
<span data-ty="input"><span class="file-path"></span>moonwall init</span>
<span data-ty>✔ Provide a label for the config file moonwall_config</span>
<span data-ty>✔ Provide a global timeout value 30000</span>
<span data-ty>✔ Provide a name for this environment default_env</span>
<span data-ty>✔ What type of network foundation is this? dev</span>
<span data-ty>✔ Provide the path for where tests for this environment are kept tests/</span>
<span data-ty>? Would you like to generate this config? (no to restart from beginning) (Y/n)</span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"label": "moonwall_config",
"defaultTestTimeout": 30000,
"environments": [
{
"name": "default_env",
"testFileDir": ["tests/"],
"foundation": {
"launchSpec": [
{
"binPath": "./node-template",
"newRpcBehaviour": true,
"ports": { "rpcPort": 9944 }
}
],
"type": "dev"
},
"connections": [
{
"name": "myconnection",
"type": "polkadotJs",
"endpoints": ["ws://127.0.0.1:9944"]
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div id="termynal" data-termynal>
<span data-ty="input"><span class="file-path"></span>moonwall test default_env -c moonwall.config</span>
<span data-ty>stdout | tests/test1.ts > 🗃️ D1 Demo suite > 📁 D1T1 Test Case</span>
<span data-ty>2025-01-21T19:27:55.624Z test:default_env Balance before: 0</span>
<span data-ty></span>
<span data-ty>stdout | tests/test1.ts > 🗃️ D1 Demo suite > 📁 D1T1 Test Case</span>
<span data-ty>2025-01-21T19:28:01.637Z test:default_env Balance after: 1000000000000000</span>
<span data-ty></span>
<span data-ty> ✓ default_env tests/test1.ts (1 test) 6443ms</span>
<span data-ty> ✓ 🗃️ D1 Demo suite > 📁 D1T1 Test Case 6028ms</span>
<span data-ty></span>
<span data-ty> Test Files 1 passed (1)</span>
<span data-ty> Tests 1 passed (1)</span>
<span data-ty> Start at 16:27:53</span>
<span data-ty> Duration 7.95s (transform 72ms, setup 0ms, collect 1.31s, tests 6.44s, environment 0ms, prepare 46ms)</span>
<span data-ty></span>
<span data-ty>✅ All tests passed</span>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import '@polkadot/api-augment';
import { describeSuite, expect } from '@moonwall/cli';
import { Keyring } from '@polkadot/api';

describeSuite({
id: 'D1',
title: 'Demo suite',
foundationMethods: 'dev',
testCases: ({ it, context, log }) => {
it({
id: 'T1',
title: 'Test Case',
test: async () => {
// Set up polkadot.js API and testing accounts
let api = context.polkadotJs();
let alice = new Keyring({ type: 'sr25519' }).addFromUri('//Alice');
let charlie = new Keyring({ type: 'sr25519' }).addFromUri('//Charlie');

// Query Charlie's account balance before transfer
const balanceBefore = (await api.query.system.account(charlie.address))
.data.free;

// Before transfer, Charlie's account balance should be 0
expect(balanceBefore.toString()).toEqual('0');
log('Balance before: ' + balanceBefore.toString());

// Transfer from Alice to Charlie
const amount = 1000000000000000;
await api.tx.balances
.transferAllowDeath(charlie.address, amount)
.signAndSend(alice);

// Wait for the transaction to be included in a block.
// This is necessary because the balance is not updated immediately.
// Block time is 6 seconds.
await new Promise((resolve) => setTimeout(resolve, 6000));

// Query Charlie's account balance after transfer
const balanceAfter = (await api.query.system.account(charlie.address))
.data.free;

// After transfer, Charlie's account balance should be 1000000000000000
expect(balanceAfter.toString()).toEqual(amount.toString());
log('Balance after: ' + balanceAfter.toString());
},
});
},
});
3 changes: 2 additions & 1 deletion develop/toolkit/parachains/.pages
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ title: Parachains
nav:
- index.md
- spawn-chains
- fork-chains
- fork-chains
0xLucca marked this conversation as resolved.
Show resolved Hide resolved
- e2e-testing
4 changes: 4 additions & 0 deletions develop/toolkit/parachains/e2e-testing/.pages
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
title: E2E Testing
nav:
- index.md
- 'Moonwall': moonwall.md
11 changes: 11 additions & 0 deletions develop/toolkit/parachains/e2e-testing/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: E2E Testing on Polkadot SDK Chains
description: Discover a suite of tools for E2E testing on Polkadot SDK-based blockchains, including configuration management, automation, and debugging utilities.
template: index-page.html
---

# E2E Testing

## In This Section

:::INSERT_IN_THIS_SECTION:::
173 changes: 173 additions & 0 deletions develop/toolkit/parachains/e2e-testing/moonwall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
title: E2E Testing with Moonwall
description: Enhance blockchain end-to-end testing with Moonwall's standardized environment setup, comprehensive configuration management, and simple network interactions.
---

# E2E Testing with Moonwall

## Introduction

Moonwall is an end-to-end testing framework designed explicitly for Polkadot SDK-based blockchain networks. It addresses one of the most significant challenges in blockchain development: managing complex test environments and network configurations.

Moonwall consolidates this complexity by providing the following:

- A centralized configuration management system that explicitly defines all network parameters
- A standardized approach to environment setup across different Substrate-based chains
- Built-in utilities for common testing scenarios and network interactions

Developers can focus on writing meaningful tests rather than managing infrastructure complexities or searching through documentation for configuration options.

## Prerequisites

Before you begin, ensure you have the following installed:

- [Node.js](https://nodejs.org/en/){target=\_blank} (version 20.10 or higher)
- A package manager such as [npm](https://www.npmjs.com/){target=\_blank}, [yarn](https://yarnpkg.com/){target=\_blank}, or [pnpm](https://pnpm.io/){target=\_blank}

## Install Moonwall

Moonwall can be installed globally for system-wide access or locally within specific projects. This section covers both installation methods.

!!! tip
This documentation corresponds to Moonwall version `{{ dependencies.moonwall.version }}`. To avoid compatibility issues with the documented features, ensure you're using the matching version.

### Global Installation

Global installation provides system-wide access to the Moonwall CLI, making it ideal for developers working across multiple blockchain projects. Install it by running one of the following commands:

=== "npm"

```bash
npm install -g @moonwall/cli@{{ dependencies.moonwall.version }}
```

=== "pnpm"

```bash
pnpm -g install @moonwall/cli@{{ dependencies.moonwall.version }}
```

=== "yarn"

```bash
yarn global add @moonwall/cli@{{ dependencies.moonwall.version }}
```

Now, you can run the `moonwall` command from your terminal.

### Local Installation

Local installation is recommended for better dependency management and version control within a specific project. First, initialize your project:

```bash
mkdir my-moonwall-project
cd my-moonwall-project
npm init -y
```

Then, install it as a local dependency:

=== "npm"

```bash
npm install @moonwall/cli@{{ dependencies.moonwall.version }}
```

=== "pnpm"

```bash
pnpm install @moonwall/cli@{{ dependencies.moonwall.version }}
```

=== "yarn"

```bash
yarn add @moonwall/cli@{{ dependencies.moonwall.version }}
```

## Initialize Moonwall

The `moonwall init` command launches an interactive wizard to create your configuration file:

```bash
moonwall init
```

During setup, you will see prompts for the following parameters:

- **`label`** - identifies your test configuration
- **`global timeout`** - maximum time (ms) for test execution
- **`environment name`** - name for your testing environment
- **`network foundation`** - type of blockchain environment to use
- **`tests directory`** - location of your test files

Select `Enter` to accept defaults or input custom values. You should see something like this:

--8<-- 'code/develop/toolkit/parachains/e2e-testing/moonwall/init.html'

The wizard generates a `moonwall.config` file:

```json
--8<-- 'code/develop/toolkit/parachains/e2e-testing/moonwall/init-moonwall.config.json'
```

The default configuration requires specific details about your blockchain node and test requirements:

- The `foundation` object defines how your test blockchain node will be launched and managed. The dev foundation, which runs a local node binary, is used for local development

For more information about available options, check the [Foundations](https://moonsong-labs.github.io/moonwall/guide/intro/foundations.html){target=\_blank} section.

- The `connections` array specifies how your tests will interact with the blockchain node. This typically includes provider configuration and endpoint details

A provider is a tool that allows you or your application to connect to a blockchain network and simplifies the low-level details of the process. A provider handles submitting transactions, reading state, and more. For more information on available providers, check the [Providers supported](https://moonsong-labs.github.io/moonwall/guide/intro/providers.html#providers-supported){target=\_blank} page in the Moonwall documentation.

Here's a complete configuration example for testing a local node using Polkadot.js as a provider:

```json
--8<-- 'code/develop/toolkit/parachains/e2e-testing/moonwall/moonwall.config.json'
```

## Writing Tests

Moonwall uses the [`describeSuite`](https://github.com/Moonsong-Labs/moonwall/blob/7568048c52e9f7844f38fb4796ae9e1b9205fdaa/packages/cli/src/lib/runnerContext.ts#L65){target=\_blank} function to define test suites, like using [Mocha](https://mochajs.org/){target=\_blank}. Each test suite requires the following:

- **`id`** - unique identifier for the suite
- **`title`** - descriptive name for the suite
- **`foundationMethods`** - specifies the testing environment (e.g., `dev` for local node testing)
- **`testCases`** - a callback function that houses the individual test cases of this suite

The following example shows how to test a balance transfer between two accounts:

```ts
--8<-- 'code/develop/toolkit/parachains/e2e-testing/moonwall/test1.ts'
```

This test demonstrates several key concepts:

- Initializing the Polkadot.js API through Moonwall's context and setting up test accounts
- Querying on-chain state
- Executing transactions
- Waiting for block inclusion
- Verifying results using assertions

## Running the Tests

Execute your tests using the `test` Moonwall CLI command. For the default environment setup run:

```bash
moonwall test default_env -c moonwall.config
```

The test runner will output detailed results showing:

- Test suite execution status
- Individual test case results
- Execution time
- Detailed logs and error messages (if any)

Example output:
--8<-- 'code/develop/toolkit/parachains/e2e-testing/moonwall/output.html'

## Where to Go Next

For a comprehensive guide to Moonwall's full capabilities, available configurations, and advanced usage, see the official [Moonwall](https://moonsong-labs.github.io/moonwall/){target=\_blank} documentation.
1 change: 1 addition & 0 deletions develop/toolkit/parachains/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This section explores essential tools for blockchain testing, forking live netwo

- [Use Zombienet to spawn a chain](/develop/toolkit/parachains/spawn-chains/zombienet/get-started/)
- [Use Chopsticks to fork a chain](/develop/toolkit/parachains/fork-chains/chopsticks/get-started/)
- [Use Moonwall to execute E2E testing](/develop/toolkit/parachains/e2e-testing/moonwall/)

## In This Section

Expand Down
10 changes: 5 additions & 5 deletions variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ dependencies:
polkadot_sdk_solochain_template:
repository_url: https://github.com/paritytech/polkadot-sdk-solochain-template
version: v0.0.2
polkadot_sdk:
repository_url: https://github.com/paritytech/polkadot-sdk
# version: v1.16.2-rc1
stable_version: polkadot-stable2412
polkadot_js_api:
version: v15.0.2
srtool:
Expand All @@ -30,4 +26,8 @@ dependencies:
polkadot_sdk:
repository_url: https://github.com/paritytech/polkadot-sdk
version: polkadot-stable2412
docker_image_version: stable2412
docker_image_version: stable2412
stable_version: polkadot-stable2412
moonwall:
repository_url: https://github.com/Moonsong-Labs/moonwall
version: 5.9.1
Loading