事件工厂与场景构建器
约 988 字大约 3 分钟
2026-03-19
构造测试事件和声明式场景测试
目录
1. 事件工厂
ncatbot.testing 提供 8 个工厂函数,覆盖消息、请求、通知三大类事件。
消息事件
from ncatbot.testing import group_message, private_message
# 群消息
event = group_message("hello")
event = group_message("hello", group_id="888", user_id="777", nickname="小明")
# 私聊消息
event = private_message("hi")
event = private_message("hi", user_id="777")请求事件
from ncatbot.testing import friend_request, group_request
# 好友请求
event = friend_request(user_id="777", comment="我是小明")
# 加群请求
event = group_request(user_id="777", group_id="888", sub_type="add")通知事件
from ncatbot.testing import group_increase, group_decrease, group_ban, poke
# 群成员增加
event = group_increase(user_id="777", group_id="888")
# 群成员减少(被踢)
event = group_decrease(user_id="777", group_id="888", sub_type="kick")
# 群禁言(10 分钟)
event = group_ban(user_id="777", group_id="888", duration=600)
# 戳一戳
event = poke(user_id="777", target_id="10001", group_id="888")默认值一览
| 参数 | 默认值 | 说明 |
|---|---|---|
text | "hello" | 仅消息事件 |
group_id | "100200" | 群号 |
user_id | "99999" | 发送者 QQ |
self_id | "10001" | Bot QQ |
nickname | "测试用户" | 仅消息事件 |
message_id | 自增 | 自动递增,无需手动指定 |
自定义消息结构
默认情况下,group_message("hello") 会生成纯文本消息段。如果需要自定义消息结构:
# 自定义 message 段(at + 文本)
event = group_message(
"hello",
message=[
{"type": "at", "data": {"qq": "10001"}},
{"type": "text", "data": {"text": " hello"}},
],
raw_message="[CQ:at,qq=10001] hello",
)**extra 扩展
所有工厂函数支持 **extra 传入额外字段:
event = group_message("hello", custom_field="value")2. Scenario 构建器
Scenario 提供声明式链式 API,将「注入 → 等待 → 断言」流程写为可读的测试场景。
基础用法
from ncatbot.testing import Scenario, group_message
await (
Scenario("群消息回复")
.inject(group_message("hello"))
.settle()
.assert_api_called("send_group_msg")
.run(harness)
)方法链一览
| 方法 | 说明 |
|---|---|
.inject(event) | 注入一个事件 |
.inject_many(events) | 注入多个事件 |
.settle(delay=0.05) | 等待 handler 处理 |
.assert_api_called(action, **match) | 断言 API 被调用,可选参数匹配 |
.assert_api_not_called(action) | 断言 API 未被调用 |
.assert_api_count(action, count) | 断言调用次数 |
.assert_that(predicate, desc) | 自定义断言(接收 harness) |
.reset_api() | 清空调用记录 |
.run(harness) | 执行场景(async) |
assert_api_called 参数匹配
.assert_api_called("send_group_msg", group_id="888")这会在所有 send_group_msg 调用中查找 kwargs 包含 group_id="888" 的调用。
自定义断言
def check_message_content(h):
call = h.last_api_call("send_group_msg")
assert "hello" in str(call.args)
await (
Scenario("检查消息内容")
.inject(group_message("hello"))
.settle()
.assert_that(check_message_content, "回复中包含 hello")
.run(harness)
)3. 组合场景示例
多步对话
await (
Scenario("注册流程")
.inject(group_message("注册", group_id="100", user_id="99"))
.settle(0.1)
.assert_api_called("send_group_msg")
.reset_api()
.inject(group_message("张三", group_id="100", user_id="99"))
.settle(0.1)
.assert_api_called("send_group_msg")
.run(harness)
)权限拦截
await (
Scenario("非管理员被拦截")
.inject(group_message("/ban 777", group_id="100", user_id="99"))
.settle()
.assert_api_not_called("set_group_ban")
.run(harness)
)批量事件
from ncatbot.testing import group_message, private_message
await (
Scenario("多类型事件")
.inject_many([
group_message("a"),
private_message("b"),
group_message("c"),
])
.settle(0.1)
.assert_api_count("send_group_msg", 2)
.assert_api_count("send_private_msg", 1)
.run(harness)
)4. 自动冒烟测试
ncatbot.testing 提供插件自动发现和冒烟测试代码生成。
discover_testable_plugins
from ncatbot.testing import discover_testable_plugins
manifests = discover_testable_plugins(Path("examples/"))
for m in manifests:
print(m.name, m.version)扫描目录下所有包含 manifest.toml 的子文件夹,返回 PluginManifest 列表。
generate_smoke_tests
from ncatbot.testing import generate_smoke_tests
code = generate_smoke_tests(manifests)
Path("tests/test_smoke.py").write_text(code)生成的冒烟测试为每个插件验证:
- 加载成功
- 卸载成功
- 收到基础群消息不崩溃
pytest 插件集成
在 conftest.py 中注册 pytest 插件,可使用 --plugin-dir 和 @pytest.mark.plugin:
# conftest.py
from ncatbot.testing import * # noqapython -m pytest --plugin-dir=examples/ -v5. NapCat E2E 简介
除了 Mock 环境下的离线测试,NcatBot 还支持连接真实 NapCat 的端到端测试。
E2E 测试位于 tests/e2e/napcat/run.py,需要:
- 运行中的 NapCat 实例
- 配置环境变量:
NAPCAT_TEST_GROUP、NAPCAT_TEST_USER
$env:NAPCAT_TEST_GROUP="123456"
$env:NAPCAT_TEST_USER="654321"
python tests/e2e/napcat/run.pyNapCat E2E 测试主要用于框架开发者验证真实协议兼容性,插件开发者通常使用 Mock 测试即可。
相关资源
| 资源 | 链接 |
|---|---|
| Harness 详解 | 2.harness.md |
| 测试 API 参考 | reference/testing/ |
| Factory + Mock 完整签名 | reference/testing/2_factory_scenario_mock.md |
版权所有
版权归属:huan-yp
