# 单元测试说明

## 测试框架

本项目使用 `pytest` 作为测试框架，支持异步测试和数据库测试。

## 运行测试

### 运行所有测试

```bash
cd backend
pytest
```

### 运行特定测试文件

```bash
pytest tests/test_auth.py
```

### 运行特定测试类或函数

```bash
pytest tests/test_auth.py::TestAuth::test_register_user
```

### 运行带标记的测试

```bash
# 只运行单元测试
pytest -m unit

# 只运行工作流相关测试
pytest -m workflow

# 只运行认证相关测试
pytest -m auth
```

### 运行并显示覆盖率

```bash
pytest --cov=app --cov-report=html
```

## 测试标记

- `@pytest.mark.unit` - 单元测试
- `@pytest.mark.integration` - 集成测试
- `@pytest.mark.slow` - 慢速测试（需要网络或数据库）
- `@pytest.mark.api` - API测试
- `@pytest.mark.workflow` - 工作流测试
- `@pytest.mark.auth` - 认证测试

## 测试结构

```
tests/
├── __init__.py
├── conftest.py          # 共享fixtures和配置
├── test_auth.py         # 认证API测试
├── test_workflows.py    # 工作流API测试
├── test_workflow_engine.py  # 工作流引擎测试
└── test_workflow_validator.py  # 工作流验证器测试
```

## Fixtures

### `db_session`
创建测试数据库会话，每个测试函数都会获得一个独立的会话。

### `client`
创建FastAPI测试客户端，用于API测试。

### `authenticated_client`
创建已认证的测试客户端，自动注册用户并登录。

### `test_user_data`
提供测试用户数据。

### `sample_workflow_data`
提供示例工作流数据。

## 测试数据库

测试使用SQLite内存数据库，每个测试函数都会：
1. 创建所有表
2. 执行测试
3. 删除所有表

这样可以确保测试之间的隔离性。

## 编写新测试

### 示例：API测试

```python
@pytest.mark.unit
@pytest.mark.api
class TestMyAPI:
    def test_my_endpoint(self, authenticated_client):
        response = authenticated_client.get("/api/v1/my-endpoint")
        assert response.status_code == 200
```

### 示例：服务测试

```python
@pytest.mark.unit
class TestMyService:
    @pytest.mark.asyncio
    async def test_my_service_method(self):
        service = MyService()
        result = await service.my_method()
        assert result is not None
```

## 注意事项

1. **测试隔离**：每个测试函数都应该独立，不依赖其他测试的执行顺序。

2. **数据库清理**：使用 `db_session` fixture 确保每个测试都有干净的数据库。

3. **异步测试**：使用 `@pytest.mark.asyncio` 标记异步测试函数。

4. **标记测试**：使用适当的标记（`@pytest.mark.unit` 等）来组织测试。

5. **测试数据**：使用 fixtures 提供测试数据，避免硬编码。

## CI/CD集成

在CI/CD流程中运行测试：

```yaml
# .github/workflows/test.yml
- name: Run tests
  run: |
    cd backend
    pytest --cov=app --cov-report=xml
```
