快速入门:插件测试
约 924 字大约 3 分钟
2026-03-19
5 分钟为你的插件编写第一个自动化测试
目录
1. 前置条件
安装测试依赖:
uv pip install ncatbot55[test]这会安装 pytest、pytest-asyncio、pytest-cov 等工具。
在项目根目录的 pyproject.toml 中添加配置:
[tool.pytest.ini_options]
asyncio_mode = "strict"
testpaths = ["tests"]
asyncio_mode = "strict"要求所有异步测试显式标记@pytest.mark.asyncio或使用全局pytestmark。
2. 测试目录结构
推荐的项目结构:
my-bot/
├── plugins/
│ └── my_plugin/
│ ├── manifest.toml
│ └── main.py
├── tests/
│ ├── conftest.py # 共享 fixtures
│ └── test_my_plugin.py # 插件测试
├── main.py
└── pyproject.tomlconftest.py 可以放共享的 fixture:
import pytest
from pathlib import Path
@pytest.fixture
def plugins_dir():
return Path(__file__).resolve().parent.parent / "plugins"3. 第一个测试
创建 tests/test_my_plugin.py:
"""my_plugin 插件测试"""
import pytest
from pathlib import Path
from ncatbot.testing import PluginTestHarness
from ncatbot.testing.factories.qq import group_message
pytestmark = pytest.mark.asyncio(mode="strict")
PLUGIN_NAME = "my_plugin"
@pytest.fixture
def plugins_dir():
return Path(__file__).resolve().parent.parent / "plugins"
async def test_plugin_loads(plugins_dir):
"""插件可以正常加载"""
async with PluginTestHarness(
plugin_names=[PLUGIN_NAME],
plugins_dir=plugins_dir,
) as h:
assert PLUGIN_NAME in h.loaded_plugins
async def test_hello_command(plugins_dir):
"""群里发 'hello' → 回复消息"""
async with PluginTestHarness(
plugin_names=[PLUGIN_NAME],
plugins_dir=plugins_dir,
) as h:
await h.inject(group_message("hello", group_id="100", user_id="99"))
await h.settle()
h.assert_api("send_group_msg").called()测试三件套
所有测试都遵循同一模式:
inject → settle → assert- inject — 注入一个事件(模拟用户发消息 / 入群 / 加好友等)
- settle — 等待 handler 完成处理
- assert — 用 fluent 断言验证 MockAPI 是否收到了预期的调用
4. 事件工厂基础
ncatbot.testing.factories 按平台组织事件工厂函数:
from ncatbot.testing.factories.qq import group_message, private_message
# 群消息 — 最常用
event = group_message("hello", group_id="123", user_id="456")
# 私聊消息
event = private_message("hi", user_id="456")所有工厂函数返回经过 model_validate 验证的合法数据模型,可直接注入 Harness。
自定义参数通过关键字参数传入,未指定的使用默认值:
# 使用默认值(group_id="100200", user_id="99999")
event = group_message("test")
# 自定义发送者信息
event = group_message(
"test",
group_id="888",
user_id="777",
nickname="自定义昵称",
)5. 运行测试
# 运行所有测试
python -m pytest tests/ -v
# 运行单个文件
python -m pytest tests/test_my_plugin.py -v
# 带覆盖率报告
python -m pytest tests/ --cov=plugins --cov-report=term-missingVSCode 中也可使用 Debug 配置运行测试(参见 开发环境搭建)。
6. 关键概念速查
| 概念 | 说明 |
|---|---|
PluginTestHarness | 插件测试编排器,选择性加载指定插件,提供事件注入和 fluent 断言 |
TestHarness | 多平台基础编排器(不加载插件),PluginTestHarness 的父类 |
group_message() | QQ 事件工厂函数,构造群消息事件 |
private_message() | QQ 事件工厂函数,构造私聊消息事件 |
inject(event) | 向 Harness 注入一个事件 |
settle(delay) | 等待 handler 处理完成(默认 0.05 秒) |
assert_api(action).called() | Fluent 断言:检查 API 是否被调用 |
assert_api(action).times(n) | Fluent 断言:检查调用次数 |
assert_api(action).with_params(k=v) | Fluent 断言:参数匹配 |
assert_api(action).with_text("text") | Fluent 断言:文本匹配(跨平台感知) |
reset_api() | 清空 API 调用记录(多步测试必备) |
API action 名称速查
| action | 说明 |
|---|---|
"send_group_msg" | 发送群消息 |
"send_private_msg" | 发送私聊消息 |
"delete_msg" | 撤回消息 |
"set_group_kick" | 踢出群成员 |
"set_group_ban" | 群禁言 |
完整列表参见 MockBotAPI 参考。
7. 下一步
| 我想… | 去看 |
|---|---|
| 深入了解 Harness 能力 | Harness 详解 |
| 学习 Scenario 链式测试 | 工厂与场景 |
| 查完整 API 签名 | 测试 API 参考 |
版权所有
版权归属:MI
