mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-27 01:23:55 +08:00
- Add browser-compatible test files (no npm required) - recorder.test.browser.js: 8 tests for microphone and HTTP detection - tools.test.browser.js: 5 tests for Live2D actions and error handling - Add test runner (test-runner.html) with built-in test framework - Add null safety checks in tools.js for DOM element access - Add documentation (English and Chinese versions) - README_TESTS.md / README_TESTS_CN.md: Complete test guide - QUICK_START_TEST.md / QUICK_START_TEST_CN.md: Quick start guides - Total: 13 unit tests covering microphone detection, HTTP detection, Live2D actions, and error handling
3.9 KiB
3.9 KiB
单元测试指南
本目录包含 xiaozhi 测试页面模块的单元测试。
摘要
- 测试总数: 13 个单元测试
- 测试文件: 2 个浏览器兼容的测试文件
- 测试运行器: 基于浏览器(无需 npm)
- 测试覆盖: 麦克风检测、HTTP 检测、Live2D 动作、错误处理
测试文件
js/core/audio/recorder.test.browser.js- 浏览器兼容的麦克风可用性检测和 HTTP 非本地访问检测测试js/core/mcp/tools.test.browser.js- 浏览器兼容的 MCP 工具和 Live2D 动作执行测试
注意: .browser.js 版本无需任何 npm 依赖。它们使用内置在 test-runner.html 中的简单测试框架。
运行测试
基于浏览器的测试运行器(无需 npm!)
- 启动本地服务器:
cd main/xiaozhi-server/test
python -m http.server 8007
-
在浏览器中打开
http://localhost:8007/test-runner.html -
点击 "▶ Run All Tests"(运行所有测试)按钮
就这么简单!无需 npm,无需 package.json,无需任何依赖。
测试覆盖
recorder.test.browser.js
- ✅
checkMicrophoneAvailability()- 当麦克风可用时返回 true - ✅
checkMicrophoneAvailability()- 当麦克风不可用时返回 false - ✅
checkMicrophoneAvailability()- 当浏览器不支持 getUserMedia 时返回 false - ✅
isHttpNonLocalhost()- 对于 HTTP 非本地访问返回 true - ✅
isHttpNonLocalhost()- 对于 localhost 返回 false - ✅
isHttpNonLocalhost()- 对于 127.0.0.1 返回 false - ✅
isHttpNonLocalhost()- 对于私有 IP 地址返回 false - ✅
isHttpNonLocalhost()- 对于 HTTPS 协议返回 false
tools.test.browser.js
- ✅
executeMcpTool('live2d.smile')- 执行 FlickUp 动作 - ✅
executeMcpTool('live2d.wave')- 执行 Tap 动作 - ✅
executeMcpTool('live2d.action')- 执行自定义动作 - ✅
executeMcpTool()- 优雅处理缺失的 Live2D 管理器 - ✅
executeMcpTool()- 优雅处理未知工具
编写新测试
添加新功能时,创建一个遵循以下模式的 .browser.js 测试文件:
// your-module.test.browser.js
import { yourFunction } from './your-module.js';
describe('您的功能', () => {
beforeEach(() => {
// 设置模拟并重置状态
vi.clearAllMocks();
});
test('应该执行某些操作', () => {
// 准备
const input = 'test';
// 执行
const result = yourFunction(input);
// 断言
expect(result).toBe('expected');
});
});
模拟指南
- 使用
vi.fn()创建函数模拟 - 使用
vi.fn().mockResolvedValue(value)创建解析的异步模拟 - 使用
vi.fn().mockRejectedValue(error)创建拒绝的异步模拟 - 在
beforeEach中使用vi.clearAllMocks()重置状态 - 模拟浏览器 API(
navigator、window.location、localStorage、fetch) - 需要时模拟 DOM 元素(
document.getElementById等)
可用的测试函数
浏览器测试框架提供:
describe(name, fn)- 定义测试套件test(name, fn)- 定义测试用例beforeEach(fn)- 在每个测试之前运行afterEach(fn)- 在每个测试之后运行expect(actual)- 断言对象,包含:.toBe(expected)- 严格相等.toHaveBeenCalled()- 函数已被调用.toHaveBeenCalledWith(...args)- 函数已使用特定参数调用.toContain(substring)- 字符串包含子字符串
vi.fn(impl?)- 创建模拟函数vi.clearAllMocks()- 清除所有模拟
注意事项
- 测试使用 ES 模块(
import/export) - 测试直接在浏览器中运行(无需 Node.js)
- 无需 npm 依赖 - 所有内容都是自包含的
- 测试运行器(
test-runner.html)包含一个简单的测试框架 - 点击 "Run All Tests"(运行所有测试)时自动加载测试