Substrate应用抛硬币游戏(二) - 编写测试和UI

作者:Kaichao

在之前的文章 Substrate应用 - 抛硬币游戏(一),我们完成了runtime的开发,从而实现了一个自定义功能(即抛硬币游戏)的区块链网络。现在让我们来看一下如何编写测试代码和UI,你也可以直接看最终的模块代码UI代码

测试

重要性

为功能模块编写测试,是软件开发过程中不可缺省的一个环节,完备的测试能够:

  • 确保代码的执行符合预期;
  • 增强重构时的信心;
  • 从代码的使用角度,提升代码的设计等。

通常情况下,测试可以分为以下几种:

  • 单元测试,mock实现代码中的依赖如其它功能模块,仅测试当前函数的功能;
  • 集成测试,不mock实现代码中的依赖,对多个功能模块整体考虑,进行测试;
  • End to End 测试,是面向当前系统与依赖的第三方服务之间的测试。

当我们在使用Substrate进行开发时,主要会使用到单元测试和集成测试的方法,对于不同的场景,可以按需选择。一个最佳实践是,确保自定义的runtime模块有良好的测试覆盖

Rust 测试代码

Rust测试代码通常会和实现代码放在同一个文件或相同的目录下,取决于测试代码的数量,更多内容可以参考Rust book。下面是一个简单的测试用例:

pub fn add_two(a: i32) -> i32 {
    a + 2
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add_two() {
        assert_eq!(4, add_two(2));
    }
}

一些需要注意的点包括:

  • 测试代码使用属性#[cfg(test)]进行标识
  • use super::*用来引入当前模块的功能代码
  • 测试函数通过属性#[test]进行标识
  • 断言方式有:
    • 表达式的值为true:assert!(expression)
    • 表达式的值是期望的值:assert_eq!(expected, expression)
    • 表达式的值不是其它不相关的值:assert_ne!(other, expression)
    • 异常发生:#[should_panic]
    • Substrate提供了自定义的断言:
      • 结果为Ok(())assert_ok!(expreesion)
      • 结果为Err(error_info)assert_err!(expression, error_info)
      • 结果为Err(error_info),并且不修改存储状态assert_noop!(expression, error_info)

运行测试

// 运行当前目录下的src目录和tests目录下的所有测试
cargo test

// 运行当前工作空间的所有package下的测试
cargo test --all

// 运行runtime路径下的所有测试,由cargo.toml的`[dependencies.demo-node-runtime]`标识
cargo test -p demo-node-runtime

// 运行runtime路径下单个模块的测试
cargo test -p demo-node-runtime mymodule

// 获取更多帮助信息
cargo test --help

运行结果大致如下:

running 5 tests
test mymodule::tests::it_works_for_default_value ... ok
test mymodule::tests::play_should_work_for_lose ... ok
test mymodule::tests::set_payment_should_work ... ok
test mymodule::tests::play_should_work_for_win ... ok
test mymodule::tests::play_security_check_should_work ... ok

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out

Runtime 测试

为了测试我们的runtime模块,需要首先引入相关的实现代码和依赖,

use super::*;

use runtime_io::with_externalities;
use primitives::{H256, Blake2Hasher};
// --snip--

Runtime模块的功能被封装在一个结构体中,这里我们定义了一个mock的Test runtime结构体:

pub struct Test;

Test runtime需要实现被测模块以及所依赖的runtime模块的配置接口,回忆一下我们的模块接口定义,自定义的模块接口继承balances的接口,而

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值