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:
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 5.9.1
. 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:
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:
Then, install it as a local dependency:
Initialize Moonwall¶
The moonwall init
command launches an interactive wizard to create your configuration file:
During setup, you will see prompts for the following parameters:
label
- identifies your test configurationglobal timeout
- maximum time (ms) for test executionenvironment name
- name for your testing environmentnetwork foundation
- type of blockchain environment to usetests directory
- location of your test files
Select Enter
to accept defaults or input custom values. You should see something like this:
The wizard generates a moonwall.config
file:
{
"label": "moonwall_config",
"defaultTestTimeout": 30000,
"environments": [
{
"name": "default_env",
"testFileDir": ["tests/"],
"foundation": {
"type": "dev"
}
}
]
}
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 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 page in the Moonwall documentation.
Here's a complete configuration example for testing a local node using Polkadot.js as a provider:
{
"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"]
}
]
}
]
}
Writing Tests¶
Moonwall uses the describeSuite
function to define test suites, like using Mocha. Each test suite requires the following:
id
- unique identifier for the suitetitle
- descriptive name for the suitefoundationMethods
- 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:
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());
},
});
},
});
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:
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:
Where to Go Next¶
For a comprehensive guide to Moonwall's full capabilities, available configurations, and advanced usage, see the official Moonwall documentation.
| Created: January 28, 2025