返回顶部
g

generate-tests生成测试套件

Creates comprehensive test suites for Move contracts with 100% coverage requirement. Triggers on: 'generate tests',

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 1.0.0
安全检测
已通过
155
下载量
免费
免费
0
收藏
概述
安装方式
版本历史

generate-tests

生成测试技能

概述

本技能为Move合约生成全面的测试套件,要求100%行覆盖率。测试验证:

  • - ✅ 正常路径(功能正常)
  • ✅ 访问控制(阻止未授权用户)
  • ✅ 输入验证(拒绝无效输入)
  • ✅ 边界情况(边界、限制、空状态)

关键规则: 未达到100%测试覆盖率绝不部署。

核心工作流

步骤1:创建测试模块

move
#[test_only]
module myaddr::mymodule_tests {
use myaddr::mymodule::{Self, MyObject};
use aptos_framework::object::{Self, Object};
use std::string;
use std::signer;

// 测试常量
const ADMIN_ADDR: address = @0x100;
const USER_ADDR: address = @0x200;
const ATTACKER_ADDR: address = @0x300;

// ========== 设置辅助函数 ==========
// (可复用的设置函数)

// ========== 正常路径测试 ==========
// (基本功能)

// ========== 访问控制测试 ==========
// (阻止未授权访问)

// ========== 输入验证测试 ==========
// (拒绝无效输入)

// ========== 边界情况测试 ==========
// (边界和限制)
}

步骤2:编写正常路径测试

测试基本功能正常:

move
#[test(creator = @0x1)]
public fun testcreateobject_succeeds(creator: &signer) {
// 执行
let obj = mymodule::createmy_object(
creator,
string::utf8(bTest Object)
);

// 验证
assert!(object::owner(obj) == signer::address_of(creator), 0);
}

#[test(owner = @0x1)]
public fun testupdateobject_succeeds(owner: &signer) {
// 设置
let obj = mymodule::createmy_object(owner, string::utf8(bOld Name));

// 执行
let new_name = string::utf8(bNew Name);
mymodule::updateobject(owner, obj, new_name);

// 验证(如果有视图函数)
// assert!(mymodule::getobjectname(obj) == newname, 0);
}

#[test(owner = @0x1, recipient = @0x2)]
public fun testtransferobject_succeeds(
owner: &signer,
recipient: &signer
) {
let recipientaddr = signer::addressof(recipient);

// 设置
let obj = mymodule::createmy_object(owner, string::utf8(bObject));
assert!(object::owner(obj) == signer::address_of(owner), 0);

// 执行
mymodule::transferobject(owner, obj, recipient_addr);

// 验证
assert!(object::owner(obj) == recipient_addr, 1);
}

步骤3:编写访问控制测试

测试阻止未授权访问:

move
#[test(owner = @0x1, attacker = @0x2)]
#[expectedfailure(abortcode = mymodule::ENOT_OWNER)]
public fun testnonownercannotupdate(
owner: &signer,
attacker: &signer
) {
let obj = mymodule::createmy_object(owner, string::utf8(bObject));

// 攻击者尝试更新(应中止)
mymodule::updateobject(attacker, obj, string::utf8(bHacked));
}

#[test(owner = @0x1, attacker = @0x2)]
#[expectedfailure(abortcode = mymodule::ENOT_OWNER)]
public fun testnonownercannottransfer(
owner: &signer,
attacker: &signer
) {
let obj = mymodule::createmy_object(owner, string::utf8(bObject));

// 攻击者尝试转移(应中止)
mymodule::transferobject(attacker, obj, @0x3);
}

#[test(admin = @0x1, user = @0x2)]
#[expectedfailure(abortcode = mymodule::ENOT_ADMIN)]
public fun testnonadmincannotconfigure(
admin: &signer,
user: &signer
) {
mymodule::initmodule(admin);

// 普通用户尝试管理功能(应中止)
mymodule::updateconfig(user, 100);
}

步骤4:编写输入验证测试

测试拒绝无效输入:

move
#[test(user = @0x1)]
#[expectedfailure(abortcode = mymodule::EZERO_AMOUNT)]
public fun testzeroamount_rejected(user: &signer) {
my_module::deposit(user, 0); // 应中止
}

#[test(user = @0x1)]
#[expectedfailure(abortcode = mymodule::EAMOUNTTOOHIGH)]
public fun testexcessiveamount_rejected(user: &signer) {
mymodule::deposit(user, mymodule::MAXDEPOSITAMOUNT + 1); // 应中止
}

#[test(owner = @0x1)]
#[expectedfailure(abortcode = mymodule::EEMPTY_NAME)]
public fun testemptystring_rejected(owner: &signer) {
let obj = mymodule::createmy_object(owner, string::utf8(bInitial));
mymodule::updateobject(owner, obj, string::utf8(b)); // 空字符串 - 应中止
}

#[test(owner = @0x1)]
#[expectedfailure(abortcode = mymodule::ENAMETOOLONG)]
public fun teststringtoolongrejected(owner: &signer) {
let obj = mymodule::createmy_object(owner, string::utf8(bInitial));

// 超过MAXNAMELENGTH的字符串
let long_name = string::utf8(bThis is an extremely long name that exceeds the maximum allowed length);

mymodule::updateobject(owner, obj, long_name); // 应中止
}

#[test(owner = @0x1)]
#[expectedfailure(abortcode = mymodule::EZERO_ADDRESS)]
public fun testzeroaddress_rejected(owner: &signer) {
let obj = mymodule::createmy_object(owner, string::utf8(bObject));
mymodule::transferobject(owner, obj, @0x0); // 应中止
}

步骤5:编写边界情况测试

测试边界条件:

move
#[test(user = @0x1)]
public fun testmaxamount_allowed(user: &signer) {
mymodule::initaccount(user);

// 恰好MAXDEPOSITAMOUNT应正常工作
mymodule::deposit(user, mymodule::MAXDEPOSITAMOUNT);

// 验证
assert!(mymodule::getbalance(signer::addressof(user)) == mymodule::MAXDEPOSITAMOUNT, 0);
}

#[test(user = @0x1)]
public fun testmaxnamelengthallowed(user: &signer) {
// 创建恰好MAXNAMELENGTH长度的字符串
let max_name = string::utf8(b12345678901234567890123456789012); // 如果MAX=32则为32字符

// 应成功
let obj = mymodule::createmyobject(user, maxname);
}

#[test(user = @0x1)]
public fun testemptycollection_operations(user: &signer) {
let collection = mymodule::createcollection(user, string::utf8(bCollection));

// 应优雅处理空集合
assert!(mymodule::getcollection_size(collection) == 0, 0);
}

步骤6:验证覆盖率

运行测试并检查覆盖率:

bash

运行所有测试


aptos move test

运行并检查覆盖率

aptos move test --coverage

生成详细覆盖率报告

aptos move coverage source --module

验证100%覆盖率

aptos move coverage summary

覆盖率报告示例:

module: my_module
coverage: 100.0% (150/150 lines covered)

如果覆盖率 < 100%:

  1. 1. 检查报告中未覆盖的行
  2. 为缺失路径编写测试
  3. 重复直到达到100%

测试模板结构

move
#[test_only]
module myaddr::moduletests {
use my_addr::module::{Self, Type};

// ========== 设置辅助函数 ==========

fun setup_default(): Object {
// 通用设置代码
}

// ========== 正常路径测试 ==========

#[test(user = @0x1)]
public fun testbasicoperation

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 generate-tests-1776177241 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 generate-tests-1776177241 技能

通过命令行安装

skillhub install generate-tests-1776177241

下载

⬇ 下载 generate-tests v1.0.0(免费)

文件大小: 4.3 KB | 发布时间: 2026-4-17 14:55

v1.0.0 最新 2026-4-17 14:55
Initial release of "generate-tests": quickly generate Move contract test suites with full coverage.

- Provides templates and detailed guidance for testing Move contracts with 100% line coverage.
- Covers happy paths, access control, input validation, and edge cases.
- Enforces a strict rule: never deploy without 100% test coverage.
- Includes Move test code examples and coverage verification commands.
- Supports prompts like "generate tests", "add test coverage", and similar triggers.

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部