Move 事务测试

处于探索阶段的功能

本文档中描述的 Move 事务测试功能处于探索阶段。对它的支持将取决于 Aptos 社区对它的使用。

如果你是一个使用 Move 语言的智能合约开发者,那么你可以使用 Move 事务测试来编写和运行端到端的测试。

本教程将指导你使用 Aptos CLI 编写和运行端到端的 Move 事务测试的步骤。

与 Move 单元测试相比,Move 事务测试有助于验证模块内代码的正确性,Move 事务测试使你能够测试更广泛的用例,如发布 Move 模块和模块间的交互。

概述

参考 aptos_test_harness GitHub 文件夹,了解 Move 事务测试的大概样子。

一个 Move 事务测试套件由两种类型的文件组成:

  • Move 文件,以 .move 为扩展名。这些 Move 文件包含了事务测试。事务测试的执行方法是一系列 Rust clap(命令行参数解析器)命令。它们在 Move 文件中被写成注释。为了区别于正常的 Move 注释,这些事务测试命令的前缀是一个特殊的注释字符串指标 //#

  • 基线文件,以 .exp 为扩展名。当你第一次运行 aptos CLI时,这些基线文件将被创建为空。如果你第一次用 UB=1 选项运行测试,基线文件将被填充为测试输出。

快速开始

在你进入细节之前,你可以按照下面的步骤来运行一个 Move 事务测试示例,看看结果。

Step 1: 安装 Aptos CLI

确保你已经安装了 aptos,即 Aptos CLI 工具。关于如何安装和使用 aptos CLI 工具,请参阅 Aptos CLI

Step 2: 运行 Move 事务测试套件

  • 克隆或下载 aptos-core GitHub repo

  • Move 事务测试套件位于 aptos-core/aptos-move/aptos-transactional-test-harness/tests。

  • 运行 aptos CLI 命令,选项为 move transactional-test。

💡 使用 UB=1

当你运行 aptos CLI命令时,确保在第一次或你已经更新了测试时,在命令中包含 UB=1,如下所示。

UB=1 aptos move transactional-test --root-path aptos-core/aptos-move/aptos-transactional-test-harness/test
  • -root-path 指定了所有测试的位置。

  • 测试运行器沿着目录层级往下走,在名称以 .move.mvir 结尾,且带有特殊前缀 //# 的注释文件中找到测试。

  • Move 事务测试运行器运行测试并将测试的输出与基线文件进行比较。基线文件保存了第一次运行时产生的结果的内容。

🌰 举个栗子

本节介绍了如何编写和运行各种 Move 事务测试命令的例子。

创建账号

//# create_account —name Alice [--initial-coins 10000]

create_account 命令将生成一个确定的私钥、公钥对,并创建一个带名称的账户地址(上例中的 Alice)。

💡 账户中的默认余额 可以指定账户的默认代币余额,否则,将使用默认值 10000。

Publish modules

//# publish [--gas-budget 100]
module Alice::first_module {
    public entry fun foo() {
        return
    }
}

publish 命令将一个 Move 模块发布到一个指定的账户(上例中为Alice)。可以选择通过 --gas-budget 指定发布操作中,允许消耗的最大 gas 单位。

💡 --gas-budget 默认值 默认取当前账户所持有的代币余额

运行模块中脚本函数

//# run --signers Alice [--args x"68656C6C6F20776F726C64"] [--type-args "0x1::aptos_coin::AptosCoin"] [--expiration 1658432810] [--sequence-number 1] [--gas-price 1] [--show-events] -- Alice::first_module::function_name

run命令通过发送一个事务来运行模块中脚本函数。

在上面的例子中:

  • -signers指定谁签署和发送交易。

  • Alice::first_module::function_name是 Alice 地址下,first_module 模块函数的名称。

  • -args 指定要传递给脚本函数的入参。

  • -type-args如果脚本函数是一个泛型函数,则指定类型参数。

  • -expiration交易过期时间。

  • -sequence-number账户序列号。

  • -gas-price单位 gas 的费用。

  • -show-events如果指定,打印出交易事件。

执行脚本

//# run --script --signers Alice [--args x"68656C6C6F20776F726C64"] [--type-args "0x1::aptos_coin::AptosCoin"] [--expiration 1658432810] [--sequence-number 1] [--gas-price 1]
script {
    use aptos_framework::coin;
    use aptos_framework::aptos_coin::AptosCoin;

    fun main(sender: &signer, receiver: address, amount: u64) {
        coin::transfer<AptosCoin>(sender, receiver, amount);
    }
}

run 命令也可以和 --script 选项一起使用,以执行一个脚本。

查看模块下的资源

//# view --address Alice --resource Alice::first_module::resource_name

view打印出在一个地址下的资源。

  • --address:打印指定账户下的资源

  • --resource:打印该账户地址下的指定资源

View tables

//# view_table --table_handle 5713946181763753045826830927579154558 --key_type 0x1::string::String --key_value x"68656C6C6F20776F726C64" --value_type 0x1::token::Collection

view_table 通过表格的 key 来打印出表内的一个值。例如,在下面的 Move 代码中。

struct Collections has key {
    collections: Table<string::String, Collection>,
}
  • 在存储中,表collections有一个句柄存储在资源Collections中。

  • 要按键查询一个表项,我们需要知道表的句柄信息-table_handle 5713946181763753045826830927579154558

  • table_handle 是要查询的表的句柄。它可以通过view_resource命令查询。

  • -key_type是键的类型信息。要获得一个键的值,请使用-view_table选项和-key_type-key_value

  • -key_value是用于检索值的键。

  • key_type 用于对 key_value 进行反序列化,以获得一个原始键,可以用来查询存储。

  • -value_type是用于反序列化表值的类型信息。存储的返回值也必须被反序列化才有用。因此在测试过程中,也需要 -value_type

Last updated