Rust区块链开发库pallet-revive-fixtures的使用:Substrate框架中的测试工具与固定数据生成插件
Rust区块链开发库pallet-revive-fixtures的使用:Substrate框架中的测试工具与固定数据生成插件
安装
在项目目录中运行以下Cargo命令:
cargo add pallet-revive-fixtures
或者在Cargo.toml中添加以下行:
pallet-revive-fixtures = "0.5.0"
基本使用
pallet-revive-fixtures是一个用于Substrate框架的测试工具和固定数据生成插件,主要用于区块链开发中的测试场景。以下是使用示例:
use pallet_revive_fixtures::*;
use frame_support::{assert_ok, traits::OnInitialize};
#[test]
fn test_fixture_initialization() {
// 创建测试环境
new_test_ext().execute_with(|| {
// 初始化区块
run_to_block(1);
// 使用固定数据生成器
let account = fixture_account("Alice");
let balance = fixture_balance(1000);
// 断言测试
assert_ok!(SomePallet::do_something(account, balance));
// 运行到指定区块
run_to_block(10);
// 验证状态
assert_eq!(SomePallet::some_value(), expected_value);
});
}
完整示例
以下是一个更完整的测试用例示例,展示了如何使用pallet-revive-fixtures进行复杂的区块链测试:
use pallet_revive_fixtures::*;
use frame_support::{assert_ok, assert_noop};
use sp_runtime::traits::BadOrigin;
mod mock {
use super::*;
frame_support::construct_runtime!(
pub enum TestRuntime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
MyPallet: pallet_my_pallet::{Pallet, Call, Storage, Event<T>},
}
);
impl pallet_my_pallet::Config for TestRuntime {
type Event = Event;
type Currency = Balances;
}
}
use mock::*;
#[test]
fn comprehensive_pallet_test() {
new_test_ext().execute_with(|| {
// 初始化测试环境
let alice = fixture_account("Alice");
let bob = fixture_account("Bob");
let charlie = fixture_account("Charlie");
// 设置初始余额
let initial_balance = fixture_balance(1000);
assert_ok!(Balances::set_balance(RuntimeOrigin::root(), alice, initial_balance, 0));
assert_ok!(Balances::set_balance(RuntimeOrigin::root(), bob, initial_balance, 0));
// 测试正常操作
assert_ok!(MyPallet::do_operation(RuntimeOrigin::signed(alice), bob, 500));
// 验证状态变化
assert_eq!(MyPallet::some_storage_value(), expected_value);
assert_eq!(Balances::free_balance(&alice), 500);
assert_eq!(Balances::free_balance(&bob), 1500);
// 测试错误情况
assert_noop!(
MyPallet::do_operation(RuntimeOrigin::signed(charlie), alice, 100),
BadOrigin
);
// 测试事件
System::assert_last_event(
Event::MyPallet(crate::Event::OperationCompleted { from: alice, to: bob, amount: 500 })
);
// 运行多个区块测试时间相关逻辑
run_to_block(10);
assert_ok!(MyPallet::time_sensitive_operation(RuntimeOrigin::signed(alice)));
run_to_block(20);
assert_eq!(MyPallet::get_time_dependent_value(), expected_value_at_block_20);
});
}
主要功能
- 测试环境设置:
new_test_ext()
创建测试环境 - 区块模拟:
run_to_block(n)
模拟运行到指定区块 - 固定数据生成:
fixture_account(name)
生成测试账户fixture_balance(amount)
生成固定金额
- 断言辅助:简化常见断言操作
- 事件验证:方便验证事件是否触发
许可证
本库采用GPL-3.0-only许可证。
1 回复
Rust区块链开发库pallet-revive-fixtures的使用:Substrate框架中的测试工具与固定数据生成插件
概述
pallet-revive-fixtures
是Substrate框架中的一个实用工具库,主要用于简化区块链开发中的测试流程和固定数据(fixtures)生成。它为开发者提供了便捷的方法来创建测试环境和预定义数据,特别适合在开发Substrate pallet时使用。
主要功能
- 测试环境搭建:快速创建区块链运行时环境
- 固定数据生成:预定义测试数据模板
- 账户管理:测试账户的创建和管理
- 区块生成:模拟区块生成和交易处理
安装方法
在项目的Cargo.toml
中添加依赖:
[dependencies]
pallet-revive-fixtures = { git = "https://github.com/revive-network/pallet-revive-fixtures.git", branch = "main" }
基本使用方法
1. 初始化测试环境
use pallet_revive_fixtures::TestRuntime;
use frame_support::construct_runtime;
construct_runtime!(
pub enum TestRuntime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system,
// 添加你的其他pallet
ReviveFixtures: pallet_revive_fixtures,
}
);
2. 创建测试账户
use pallet_revive_fixtures::accounts;
let alice = accounts::alice();
let bob = accounts::bob();
let charlie = accounts::charlie();
3. 使用固定数据
use pallet_revive_fixtures::fixtures;
// 获取预定义的固定数据
let default_fixtures = fixtures::default();
// 使用自定义数据
let custom_fixtures = fixtures::custom()
.with_account("dave", 1000)
.with_balance("eve", 2000);
4. 在测试中使用
#[test]
fn test_my_pallet_function() {
// 初始化测试环境
let mut t = TestRuntime::new_with_fixtures(fixtures::default());
// 执行测试逻辑
t.execute_with(|| {
// 这里可以调用你的pallet函数进行测试
assert_ok!(MyPallet::some_function(Origin::signed(accounts::alice())));
});
}
高级用法
自定义固定数据模板
use pallet_revive_fixtures::{FixtureBuilder, AccountId, Balance};
let my_fixtures = FixtureBuilder::new()
.add_account(AccountId::new([1; 32]), Balance::from(1000))
.add_account(AccountId::new([2; 32]), Balance::from(2000))
.build();
模拟区块生成
use pallet_revive-fixtures::BlockSimulator;
let mut simulator = BlockSimulator::new(TestRuntime::new_with_fixtures(fixtures::default()));
// 模拟生成10个区块
simulator.generate_blocks(10);
// 在特定区块高度执行操作
simulator.at_block(5, || {
// 在第5个区块执行的操作
});
完整示例:测试投票pallet
下面是一个使用pallet-revive-fixtures
测试投票pallet的完整示例:
use frame_support::{assert_ok, assert_err, traits::{Currency, OnInitialize}};
use frame_system::RawOrigin;
use pallet_revive_fixtures::{TestRuntime, accounts, fixtures};
// 定义测试运行时
pub type AccountId = <TestRuntime as frame_system::Config>::AccountId;
pub type Balance = <<TestRuntime as pallet_balances::Config>::Currency as Currency<AccountId>>::Balance;
#[test]
fn test_voting_pallet() {
// 设置初始测试数据 - 3个账户,每个账户有1000代币
let fixtures = fixtures::custom()
.with_balance(accounts::alice(), 1000)
.with_balance(accounts::bob(), 1000)
.with_balance(accounts::charlie(), 1000);
// 初始化测试环境
let mut t = TestRuntime::new_with_fixtures(fixtures);
t.execute_with(|| {
// 创建提案
assert_ok!(VotingPallet::create_proposal(
Origin::signed(accounts::alice()),
"Proposal 1".into(),
100, // 通过所需票数
10 // 投票持续时间(区块数)
));
// 检查提案状态
let proposal = VotingPallet::proposals(0).unwrap();
assert_eq!(proposal.title, "Proposal 1");
assert_eq!(proposal.required_votes, 100);
// 进行投票
assert_ok!(VotingPallet::vote(
Origin::signed(accounts::bob()),
0, // 提案ID
true, // 赞成
50 // 投票权重
));
// 检查投票结果
let votes = VotingPallet::proposal_votes(0);
assert_eq!(votes.yes_votes, 50);
// 模拟区块前进
let mut simulator = BlockSimulator::new(t);
simulator.generate_blocks(15); // 超过投票期限
// 在区块高度15检查提案状态
simulator.at_block(15, || {
let proposal = VotingPallet::proposals(0).unwrap();
assert!(proposal.is_concluded);
assert!(!proposal.is_passed); // 50 < 100,未通过
});
});
}
注意事项
- 该库主要用于测试环境,不建议在生产环境中使用
- 固定数据应根据实际测试需求进行定制
- 在复杂场景中,可能需要结合其他测试工具一起使用
- 注意及时更新库版本以获取最新功能和修复
通过使用pallet-revive-fixtures
,开发者可以显著简化Substrate pallet的测试流程,提高开发效率和测试覆盖率。