# 学生知识图谱系统测试文档

## 概述

本文档描述了学生知识图谱可视化系统的测试策略、测试用例和运行方法。系统采用PHPUnit进行单元测试和集成测试，确保代码质量和功能正确性。

## 测试结构

```
FilamentAdmin/tests/
├── Unit/
│   ├── StudentKnowledgeGraphTest.php          # 页面和组件单元测试
│   └── Services/
│       └── KnowledgeGraphServiceTest.php      # 服务层单元测试
└── Feature/
    └── StudentKnowledgeGraphIntegrationTest.php  # 集成测试
```

## 测试文件说明

### 1. StudentKnowledgeGraphTest.php

**测试范围**:
- Filament页面类 (`StudentKnowledgeGraphPage`)
- Livewire组件类 (`StudentKnowledgeGraph`)
- 组件初始化和行为
- 私有方法测试（使用反射）

**测试用例**:
- ✅ 页面可以正常访问
- ✅ 导航菜单配置正确
- ✅ 页面渲染正确视图
- ✅ Livewire组件初始化
- ✅ 学生列表加载功能
- ✅ 选择学生加载数据
- ✅ 掌握度颜色映射
- ✅ 节点大小计算
- ✅ API失败时使用模拟数据
- ✅ 知识图谱数据结构
- ✅ 数据重置功能

### 2. KnowledgeGraphServiceTest.php

**测试范围**:
- `KnowledgeGraphService` 服务类
- API调用和响应处理
- 错误处理和容错机制
- 数据格式化

**测试用例**:
- ✅ 初始化和URL配置
- ✅ 知识列表获取和格式化
- ✅ 备用数据机制
- ✅ 多字段名处理
- ✅ 技能列表获取
- ✅ 关联关系获取
- ✅ 图谱数据导出
- ✅ 健康检查
- ✅ 掌握度颜色映射
- ✅ 学生掌握度获取
- ✅ 学生统计信息
- ✅ 数据导入功能
- ✅ 增删改查操作

### 3. StudentKnowledgeGraphIntegrationTest.php

**测试范围**:
- 完整页面加载流程
- 页面交互和状态变化
- API集成
- UI渲染和显示

**测试用例**:
- ✅ 知识图谱页面加载
- ✅ 学生下拉菜单显示
- ✅ 选择学生加载数据
- ✅ API失败显示模拟数据
- ✅ 掌握度统计显示
- ✅ 知识图谱颜色图例
- ✅ 刷新按钮功能
- ✅ 无学生选择的提示
- ✅ 知识点列表显示
- ✅ 加载状态显示
- ✅ 数据重置机制
- ✅ 表单验证
- ✅ 多学生切换
- ✅ 错误处理

## 运行测试

### 方法一：使用测试运行脚本

```bash
cd /Volumes/T9/code/math/apis/FilamentAdmin
./run-tests.sh
```

### 方法二：使用PHPUnit

```bash
# 运行所有测试
php artisan test

# 运行特定测试文件
php artisan test --filter=StudentKnowledgeGraphTest
php artisan test --filter=KnowledgeGraphServiceTest
php artisan test --filter=StudentKnowledgeGraphIntegrationTest

# 运行特定测试套件
php artisan test --testsuite=Unit
php artisan test --testsuite=Feature

# 运行特定测试方法
php artisan test --filter="it_initializes_with_correct_base_url"
```

### 方法三：运行所有相关测试

```bash
# 运行单元测试
php artisan test --testsuite=Unit --filter="KnowledgeGraph"

# 运行集成测试
php artisan test --testsuite=Feature --filter="StudentKnowledgeGraph"
```

## 测试数据

### 模拟学生数据

```php
Student::create([
    'student_id' => 1001,
    'name' => '张三',
    'grade' => '高一',
    'class_name' => '1班',
    'teacher_id' => 1,
]);
```

### 模拟掌握度数据

```php
'masteries' => [
    [
        'kp_code' => 'R01',
        'mastery_level' => 0.85,
        'confidence_level' => 0.8,
    ],
    [
        'kp_code' => 'R02',
        'mastery_level' => 0.72,
        'confidence_level' => 0.75,
    ],
],
```

### 模拟API响应

```php
Http::fake([
    'localhost:5010/api/mastery/*' => Http::response([
        'masteries' => [...],
    ], 200),
]);
```

## 断言说明

### 常见断言

```php
// 页面内容断言
$this->assertSee('学生知识图谱');
$this->assertSee('选择学生');

// 数据断言
$this->assertNotNull($component->selectedStudent);
$this->assertEquals('张三', $component->selectedStudent->name);
$this->assertCount(2, $component->students);

// 数组结构断言
$this->assertArrayHasKey('nodes', $component->knowledgePoints);
$this->assertArrayHasKey('links', $component->knowledgePoints);

// 响应状态断言
$response->assertStatus(200);
$response->assertOk();
```

## Mock和Stub

### HTTP Mock

```php
Http::fake([
    'localhost:5010/*' => Http::response($data, 200),
]);
```

### 异常模拟

```php
Http::fake([
    'localhost:5010/*' => Http::throw(new \Exception('API Error')),
]);
```

## 测试环境配置

### phpunit.xml

```xml
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.0/phpunit.xsd"
         bootstrap="tests/bootstrap.php"
         colors="true">
    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>
        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>
    </testsuites>
</phpunit>
```

## 覆盖率报告

### 生成覆盖率报告

```bash
# 生成HTML覆盖率报告
php artisan test --coverage-html coverage/

# 查看覆盖率概览
php artisan test --coverage
```

### 目标覆盖率

- **单元测试覆盖率**: > 90%
- **集成测试覆盖率**: > 80%
- **整体覆盖率**: > 85%

## 最佳实践

### 1. 测试命名

- 使用描述性的测试方法名
- 遵循 `it_` 开头或 `test_` 前缀
- 明确测试意图和行为

```php
public function it_returns_correct_mastery_colors()
public function test_loads_student_data_successfully()
```

### 2. 测试隔离

- 每个测试应该是独立的
- 使用 `setUp()` 和 `tearDown()` 方法
- 测试后清理数据

```php
protected function setUp(): void
{
    parent::setUp();
    $this->service = new KnowledgeGraphService();
}
```

### 3. 数据准备

- 使用工厂模式创建测试数据
- 使用数据库刷新确保清洁状态
- 避免硬编码数据

```php
use LazilyRefreshDatabase;

class StudentKnowledgeGraphTest extends TestCase
{
    use LazilyRefreshDatabase;
}
```

### 4. Mock使用

- Mock外部API调用
- 控制测试环境
- 模拟异常情况

```php
Http::fake([
    'localhost:5010/*' => Http::response($mockData, 200),
]);
```

### 5. 断言最佳实践

- 使用具体的断言而非泛化
- 测试预期结果而非实现细节
- 包含错误情况的测试

```php
// 好的测试
$this->assertEquals('#10b981', $color);

// 避免
$this->assertTrue($color === '#10b981');
```

## 持续集成

### GitHub Actions 配置

创建 `.github/workflows/tests.yml`:

```yaml
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
      - name: Install dependencies
        run: composer install --no-progress
      - name: Run tests
        run: ./run-tests.sh
```

## 故障排除

### 常见问题

**问题1: 测试失败 - 数据库未找到**
```bash
# 解决方案：确保测试数据库配置正确
php artisan migrate --env=testing
```

**问题2: Mock不生效**
```bash
# 解决方案：检查URL匹配模式
Http::fake([
    'localhost:5010/*' => Http::response($data, 200),  // 使用通配符
]);
```

**问题3: Livewire测试失败**
```php
// 解决方案：使用正确的测试方法
$this->livewire(Component::class)
    ->set('property', 'value')
    ->call('method')
    ->assertSee('Expected Text');
```

**问题4: 权限错误**
```bash
# 解决方案：确保测试文件可读
chmod -R 755 tests/
```

### 调试技巧

```php
// 使用dd()调试
$component = new StudentKnowledgeGraph();
dd($component->students);

// 使用Log调试
\Log::info('Debug info', $context);

// 跳过某些测试
public function test_pending_feature(): void
{
    $this->markTestSkipped('Feature pending implementation');
}
```

## 参考资源

- [PHPUnit 文档](https://phpunit.de/documentation.html)
- [Laravel 测试指南](https://laravel.com/docs/testing)
- [Livewire 测试文档](https://livewire.laravel.com/docs/testing)
- [Mockery 文档](https://docs.mockery.io/)

## 更新日志

| 日期 | 版本 | 更新内容 |
|------|------|----------|
| 2025-11-23 | v1.0 | 初始版本，添加基本测试 |
| 2025-11-23 | v1.1 | 添加集成测试和测试运行脚本 |

## 贡献指南

提交新测试时，请确保：

1. 测试遵循命名约定
2. 包含适当的断言
3. 覆盖正常和异常情况
4. 提供清晰的文档注释
5. 运行完整测试套件

---

**维护者**: Claude Code
**最后更新**: 2025-11-23
