248 lines
8.2 KiB
Python
248 lines
8.2 KiB
Python
"""BoardTeam 单元测试 — 私董会容器状态管理"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from agentkit.experts.board import BoardStatus, BoardTeam
|
|
from agentkit.experts.config import ExpertConfig
|
|
|
|
|
|
# ── 辅助函数 ──────────────────────────────────────────────
|
|
|
|
|
|
def _make_expert_configs(count: int = 3) -> list[ExpertConfig]:
|
|
"""创建测试用 ExpertConfig 列表"""
|
|
configs = []
|
|
for i in range(count):
|
|
configs.append(ExpertConfig(
|
|
name=f"expert_{i}",
|
|
agent_type="expert",
|
|
persona=f"测试专家 {i}",
|
|
thinking_style="analytical",
|
|
speaking_style="直接",
|
|
decision_framework="分析",
|
|
bound_skills=[],
|
|
is_lead=(i == 0),
|
|
task_mode="llm_generate",
|
|
prompt={"identity": f"Expert {i}"},
|
|
avatar="T",
|
|
color=f"#FF{i:02d}000",
|
|
))
|
|
return configs
|
|
|
|
|
|
# ── BoardStatus 枚举测试 ──────────────────────────────────
|
|
|
|
|
|
class TestBoardStatus:
|
|
"""BoardStatus 枚举测试"""
|
|
|
|
def test_status_values(self):
|
|
"""状态值正确"""
|
|
assert BoardStatus.FORMING.value == "forming"
|
|
assert BoardStatus.DISCUSSING.value == "discussing"
|
|
assert BoardStatus.CONCLUDING.value == "concluding"
|
|
assert BoardStatus.COMPLETED.value == "completed"
|
|
assert BoardStatus.DISSOLVED.value == "dissolved"
|
|
|
|
def test_status_is_string_enum(self):
|
|
"""BoardStatus 是 str enum"""
|
|
assert isinstance(BoardStatus.FORMING, str)
|
|
assert BoardStatus.FORMING == "forming"
|
|
|
|
|
|
# ── BoardTeam 初始化测试 ──────────────────────────────────
|
|
|
|
|
|
class TestBoardTeamInit:
|
|
"""BoardTeam 初始化测试"""
|
|
|
|
def test_default_init(self):
|
|
"""默认初始化"""
|
|
team = BoardTeam()
|
|
assert team.team_id # UUID 自动生成
|
|
assert team.status == BoardStatus.FORMING
|
|
assert team.moderator is None
|
|
assert team.experts == []
|
|
assert team.active_experts == []
|
|
assert team.member_experts == []
|
|
assert team.topic == ""
|
|
assert team.current_round == 0
|
|
assert team.max_rounds == 5
|
|
assert team.history == []
|
|
assert team.team_channel.startswith("board:")
|
|
|
|
def test_custom_max_rounds(self):
|
|
"""自定义最大轮次"""
|
|
team = BoardTeam(max_rounds=10)
|
|
assert team.max_rounds == 10
|
|
|
|
def test_custom_team_id(self):
|
|
"""自定义 team_id"""
|
|
team = BoardTeam(team_id="custom-board-123")
|
|
assert team.team_id == "custom-board-123"
|
|
assert team.team_channel == "board:custom-board-123"
|
|
|
|
|
|
# ── BoardTeam 讨论历史测试 ────────────────────────────────
|
|
|
|
|
|
class TestBoardTeamHistory:
|
|
"""BoardTeam 讨论历史管理测试"""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_add_to_history(self):
|
|
"""添加历史记录"""
|
|
team = BoardTeam()
|
|
await team.add_to_history(round=1, expert_name="expert_0", content="测试发言", role="expert")
|
|
|
|
history = team.history
|
|
assert len(history) == 1
|
|
assert history[0]["round"] == 1
|
|
assert history[0]["expert_name"] == "expert_0"
|
|
assert history[0]["content"] == "测试发言"
|
|
assert history[0]["role"] == "expert"
|
|
assert "timestamp" in history[0]
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_add_multiple_to_history(self):
|
|
"""添加多条历史记录"""
|
|
team = BoardTeam()
|
|
await team.add_to_history(1, "expert_0", "发言1", "expert")
|
|
await team.add_to_history(1, "expert_1", "发言2", "expert")
|
|
await team.add_to_history(1, "expert_0", "小结", "moderator")
|
|
|
|
assert len(team.history) == 3
|
|
|
|
def test_get_history_text_empty(self):
|
|
"""空历史返回空字符串"""
|
|
team = BoardTeam()
|
|
assert team.get_history_text() == ""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_history_text_formatted(self):
|
|
"""历史文本格式化"""
|
|
team = BoardTeam()
|
|
await team.add_to_history(1, "elon_musk", "第一性原理", "expert")
|
|
await team.add_to_history(1, "moderator", "本轮小结", "moderator")
|
|
|
|
text = team.get_history_text()
|
|
assert "elon_musk" in text
|
|
assert "第一性原理" in text
|
|
assert "moderator" in text
|
|
assert "本轮小结" in text
|
|
assert "专家发言" in text
|
|
assert "主持人小结" in text
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_history_text_up_to_round(self):
|
|
"""按轮次过滤历史"""
|
|
team = BoardTeam()
|
|
await team.add_to_history(1, "expert_0", "第一轮", "expert")
|
|
await team.add_to_history(2, "expert_0", "第二轮", "expert")
|
|
await team.add_to_history(3, "expert_0", "第三轮", "expert")
|
|
|
|
text = team.get_history_text(up_to_round=2)
|
|
assert "第一轮" in text
|
|
assert "第二轮" in text
|
|
assert "第三轮" not in text
|
|
|
|
|
|
# ── BoardTeam 用户干预测试 ────────────────────────────────
|
|
|
|
|
|
class TestBoardTeamIntervention:
|
|
"""BoardTeam 用户干预测试"""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_add_user_intervention(self):
|
|
"""添加用户干预"""
|
|
team = BoardTeam()
|
|
await team.add_user_intervention("请讨论AI伦理问题")
|
|
|
|
# 干预应出现在历史中
|
|
history = team.history
|
|
assert len(history) == 1
|
|
assert history[0]["expert_name"] == "user"
|
|
assert history[0]["content"] == "请讨论AI伦理问题"
|
|
assert history[0]["role"] == "user"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_consume_user_interventions(self):
|
|
"""消费用户干预(读取后清空)"""
|
|
team = BoardTeam()
|
|
await team.add_user_intervention("干预1")
|
|
await team.add_user_intervention("干预2")
|
|
|
|
interventions = team.consume_user_interventions()
|
|
assert len(interventions) == 2
|
|
assert "干预1" in interventions
|
|
assert "干预2" in interventions
|
|
|
|
# 再次消费应为空
|
|
assert team.consume_user_interventions() == []
|
|
|
|
|
|
# ── BoardTeam 轮次管理测试 ────────────────────────────────
|
|
|
|
|
|
class TestBoardTeamRound:
|
|
"""BoardTeam 轮次管理测试"""
|
|
|
|
def test_increment_round(self):
|
|
"""轮次递增"""
|
|
team = BoardTeam()
|
|
assert team.current_round == 0
|
|
|
|
r1 = team.increment_round()
|
|
assert r1 == 1
|
|
assert team.current_round == 1
|
|
|
|
r2 = team.increment_round()
|
|
assert r2 == 2
|
|
assert team.current_round == 2
|
|
|
|
|
|
# ── BoardTeam 状态管理测试 ────────────────────────────────
|
|
|
|
|
|
class TestBoardTeamStatus:
|
|
"""BoardTeam 状态管理测试"""
|
|
|
|
def test_set_status(self):
|
|
"""设置状态"""
|
|
team = BoardTeam()
|
|
assert team.status == BoardStatus.FORMING
|
|
|
|
team.set_status(BoardStatus.DISCUSSING)
|
|
assert team.status == BoardStatus.DISCUSSING
|
|
|
|
team.set_status(BoardStatus.COMPLETED)
|
|
assert team.status == BoardStatus.COMPLETED
|
|
|
|
team.set_status(BoardStatus.DISSOLVED)
|
|
assert team.status == BoardStatus.DISSOLVED
|
|
|
|
|
|
# ── BoardTeam 属性测试 ────────────────────────────────────
|
|
|
|
|
|
class TestBoardTeamProperties:
|
|
"""BoardTeam 属性测试"""
|
|
|
|
def test_handoff_transport_exists(self):
|
|
"""handoff_transport 存在"""
|
|
team = BoardTeam()
|
|
assert team.handoff_transport is not None
|
|
|
|
def test_workspace_exists(self):
|
|
"""workspace 存在"""
|
|
team = BoardTeam()
|
|
assert team.workspace is not None
|
|
|
|
def test_get_expert_not_found(self):
|
|
"""获取不存在的专家返回 None"""
|
|
team = BoardTeam()
|
|
assert team.get_expert("nonexistent") is None
|