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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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,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</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());
},
});
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ pallet-balances = { workspace = true, default-features = false }
[features]
default = ["std"]
std = [
"codec/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
"sp-runtime/std",
"sp-core/std",
"sp-io/std",
"pallet-balances/std",
"codec/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
"sp-runtime/std",
"sp-core/std",
"sp-io/std",
"pallet-balances/std",
]

[lints]
Expand Down
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
Empty file.
7 changes: 7 additions & 0 deletions develop/toolkit/parachains/e2e-testing/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: E2E Testing
description: TODO
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing desc

template: index-page.html
---

# E2E Testing
176 changes: 176 additions & 0 deletions develop/toolkit/parachains/e2e-testing/moonwall.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
---
title: 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 a end-to-end testing framework specifically designed for Polkadot SDK-based blockchain networks. It addresses one of the most significant challenges in blockchain development: managing complex test environments and network configurations.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if "network configurations" would be 100% accurate here. Does moonwall allow us to test p2p settings and that kind of things?

Copy link
Collaborator

@nhussein11 nhussein11 Jan 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, maybe you meant something related to the moonwall.config.json file, but even though that file defines some parameters to bootstrap the node, I think the purpose of that file is to define the settings of the test suite

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it says network configuration, it means that you can configure the parameters you use to run your blockchain network, like using a local node, a chopsticks fork, zombienet, etc. Do you think it is confusing?


Moonwall consolidates this complexity by providing:

- 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 either globally for system-wide access or locally within specific projects. This section covers both installation methods.

!!! note
his documentation corresponds to Moonwall version `{{ dependencies.moonwall.version }}`. Ensure you're using the matching version to avoid compatibility issues with the documented features.
0xLucca marked this conversation as resolved.
Show resolved Hide resolved

### 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 should be able to run the `moonwall` command from your terminal.
0xLucca marked this conversation as resolved.
Show resolved Hide resolved

### Local Installation

For better dependency management and version control within a specific project, local installation is recommended. 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'll be prompted for the following parameters:

- Label - identifies your test configuration
0xLucca marked this conversation as resolved.
Show resolved Hide resolved
- Global timeout - maximum time (ms) for test execution
- Environment name - name for your testing environment
- Network Foundation - type of blockchain environment to use
- Test Directory - location of your test files

Simply press `Enter` to accept defaults, or input custom values. The wizard generates a `moonwall.config` file:

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

The default configuration needs to be enhanced with specific details about your blockchain node and test requirements:

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

!!!note
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.

!!!note
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.

Here's a complete configuration example for testing a local node using polkadot.js as a provider:
0xLucca marked this conversation as resolved.
Show resolved Hide resolved

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

## Writing Tests

Moonwall uses the `describeSuite` function to define test suites, like using [Mocha](https://mochajs.org/){target=\_blank}. Each test suite requires:
0xLucca marked this conversation as resolved.
Show resolved Hide resolved

- `id` - unique identifier for the suite
- `title` - descriptive name for the suite
- `foundationMethods` - specifies the testing environment (e.g., `dev` for local node testing)

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 Moonwall CLI command:

```bash
moonwall test INSERT_ENVIRONMENT_NAME_HERE
0xLucca marked this conversation as resolved.
Show resolved Hide resolved
```

For the default environment setup:

```bash
moonwall test default_env
```

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

To explore Moonwall's full capabilities, refer to the official [Moonwall](https://moonsong-labs.github.io/moonwall/){target=\_blank} documentation. This provides a comprehensive guide to the available configurations and advanced usage.
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/)
0xLucca marked this conversation as resolved.
Show resolved Hide resolved

## In This Section

Expand Down
5 changes: 4 additions & 1 deletion variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ dependencies:
repository_url: https://github.com/paritytech/srtool
version: v0.16.0
docker_image_name: paritytech/srtool
docker_image_version: 1.62.0
docker_image_version: 1.62.0
moonwall:
repository_url: https://github.com/Moonsong-Labs/moonwall
version: 5.9.1
Loading