Files
xiaozhi-esp32-server/main/xiaozhi-server/test/README_TESTS.md
T
spider-yamet b7e4408a0f Add browser-based unit tests for xiaozhi test modules
- 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
2026-01-26 10:18:40 -08:00

3.9 KiB

Unit Tests Guide

This directory contains unit tests for the xiaozhi test page modules.

Summary

  • Total Tests: 13 unit tests
  • Test Files: 2 browser-compatible test files
  • Test Runner: Browser-based (no npm required)
  • Coverage: Microphone detection, HTTP detection, Live2D actions, error handling

Test Files

  • js/core/audio/recorder.test.browser.js - Browser-compatible tests for microphone availability detection and HTTP non-localhost detection
  • js/core/mcp/tools.test.browser.js - Browser-compatible tests for MCP tools and Live2D action execution

Note: The .browser.js versions work without any npm dependencies. They use a simple test framework built into test-runner.html.

Running Tests

Browser-based Test Runner (No npm required!)

  1. Start a local server:
cd main/xiaozhi-server/test
python -m http.server 8007
  1. Open http://localhost:8007/test-runner.html in your browser

  2. Click "▶ Run All Tests" button

That's it! No npm, no package.json, no dependencies needed.

Test Coverage

recorder.test.browser.js

  • checkMicrophoneAvailability() - Returns true when microphone is available
  • checkMicrophoneAvailability() - Returns false when microphone is not available
  • checkMicrophoneAvailability() - Returns false when browser doesn't support getUserMedia
  • isHttpNonLocalhost() - Returns true for HTTP non-localhost access
  • isHttpNonLocalhost() - Returns false for localhost
  • isHttpNonLocalhost() - Returns false for 127.0.0.1
  • isHttpNonLocalhost() - Returns false for private IP addresses
  • isHttpNonLocalhost() - Returns false for HTTPS protocol

tools.test.browser.js

  • executeMcpTool('live2d.smile') - Executes FlickUp action
  • executeMcpTool('live2d.wave') - Executes Tap action
  • executeMcpTool('live2d.action') - Executes custom action
  • executeMcpTool() - Handles missing Live2D manager gracefully
  • executeMcpTool() - Handles unknown tools gracefully

Writing New Tests

When adding new functionality, create a .browser.js test file that follows these patterns:

// your-module.test.browser.js
import { yourFunction } from './your-module.js';

describe('Your Feature', () => {
    beforeEach(() => {
        // Setup mocks and reset state
        vi.clearAllMocks();
    });

    test('should do something', () => {
        // Arrange
        const input = 'test';
        
        // Act
        const result = yourFunction(input);
        
        // Assert
        expect(result).toBe('expected');
    });
});

Mocking Guidelines

  • Use vi.fn() for function mocks
  • Use vi.fn().mockResolvedValue(value) for async mocks that resolve
  • Use vi.fn().mockRejectedValue(error) for async mocks that reject
  • Use vi.clearAllMocks() in beforeEach to reset state
  • Mock browser APIs (navigator, window.location, localStorage, fetch)
  • Mock DOM elements when needed (document.getElementById, etc.)

Available Test Functions

The browser test framework provides:

  • describe(name, fn) - Define a test suite
  • test(name, fn) - Define a test case
  • beforeEach(fn) - Run before each test
  • afterEach(fn) - Run after each test
  • expect(actual) - Assertion object with:
    • .toBe(expected) - Strict equality
    • .toHaveBeenCalled() - Function was called
    • .toHaveBeenCalledWith(...args) - Function was called with specific args
    • .toContain(substring) - String contains substring
  • vi.fn(impl?) - Create a mock function
  • vi.clearAllMocks() - Clear all mocks

Notes

  • Tests use ES modules (import/export)
  • Tests run directly in the browser (no Node.js needed)
  • No npm dependencies required - everything is self-contained
  • The test runner (test-runner.html) includes a simple test framework
  • Tests are automatically loaded when you click "Run All Tests"