Skip to content

Commit c19a76f

Browse files
jasinluoraychen911
authored andcommitted
test: 新增 openclaw 单元测试
1 parent db45237 commit c19a76f

45 files changed

Lines changed: 14663 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

requirements-test.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
1+
# Test framework
12
pytest
23
pytest-mock
34
pytest-asyncio
45
pyparsing>=2.4.2
56
pytest-cov
67
unittest-xml-reporting
8+
9+
# Test Eval
710
rouge-score
811
pandas
912
tabulate
13+
14+
# Test DB
1015
greenlet
1116
aiosqlite
17+
18+
# Test Optional dependencies
1219
a2a-sdk>=0.2.0
1320
protobuf>=5.29.5
1421
claude-agent-sdk>=0.1.3
1522
cloudpickle>=2.0.0
1623
ag-ui-protocol>=0.1.8
24+
nanobot-ai>=0.1.4.post5
25+
aiofiles
26+
wecom-aibot-sdk-python>=0.1.5
27+
langchain_community>=0.3.27
28+
langchain_huggingface>=0.1.0
29+
mem0ai>=1.0.3
30+
sentence-transformers

tests/server/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Tencent is pleased to support the open source community by making tRPC-Agent-Python available.
2+
#
3+
# Copyright (C) 2026 Tencent. All rights reserved.
4+
#
5+
# tRPC-Agent-Python is licensed under Apache-2.0.

tests/server/ag_ui/_core/test_event_translator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def _make_trpc_event(
8989
event.is_streaming_tool_call = Mock(return_value=is_streaming_tool_call_return)
9090
event.get_function_calls = Mock(return_value=function_calls or [])
9191
event.get_function_responses = Mock(return_value=function_responses or [])
92+
event.is_error = Mock(return_value=False)
9293
return event
9394

9495

tests/server/openclaw/__init__.py

Whitespace-only changes.

tests/server/openclaw/agent/__init__.py

Whitespace-only changes.
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
"""Unit tests for trpc_agent_sdk.server.openclaw.agent._agent."""
2+
3+
from __future__ import annotations
4+
5+
from pathlib import Path
6+
from unittest.mock import MagicMock, patch
7+
8+
import pytest
9+
10+
from trpc_agent_sdk.server.openclaw.agent._agent import (
11+
create_agent,
12+
create_model,
13+
create_worker_agent,
14+
)
15+
16+
17+
def _make_config(workspace, **overrides):
18+
defaults = dict(
19+
model_api_key="test-key",
20+
model_base_url="http://localhost:8000",
21+
model_name="gpt-4",
22+
restrict_to_workspace=True,
23+
temperature=0.7,
24+
max_tokens=4096,
25+
)
26+
defaults.update(overrides)
27+
28+
config = MagicMock()
29+
config.workspace = workspace
30+
config.model_api_key = defaults["model_api_key"]
31+
config.model_base_url = defaults["model_base_url"]
32+
config.model_name = defaults["model_name"]
33+
config.model_extra_headers = {}
34+
config.agent = MagicMock()
35+
config.agent.temperature = defaults["temperature"]
36+
config.agent.max_tokens = defaults["max_tokens"]
37+
config.agent.instruction = ""
38+
config.agent.system_prompt = ""
39+
config.tools = MagicMock()
40+
config.tools.restrict_to_workspace = defaults["restrict_to_workspace"]
41+
config.tools.web = MagicMock()
42+
config.tools.web.search = MagicMock()
43+
config.tools.web.proxy = None
44+
config.tools.mcp_servers = []
45+
config.personal = []
46+
return config
47+
48+
49+
class TestCreateModel:
50+
51+
def test_missing_api_key_raises(self, tmp_path):
52+
config = _make_config(tmp_path, model_api_key="")
53+
with pytest.raises(ValueError, match="Model config missing"):
54+
create_model(config)
55+
56+
def test_missing_base_url_raises(self, tmp_path):
57+
config = _make_config(tmp_path, model_base_url="")
58+
with pytest.raises(ValueError, match="Model config missing"):
59+
create_model(config)
60+
61+
def test_missing_model_name_raises(self, tmp_path):
62+
config = _make_config(tmp_path, model_name="")
63+
with pytest.raises(ValueError, match="Model config missing"):
64+
create_model(config)
65+
66+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.OpenAIModel")
67+
def test_success(self, mock_openai_model, tmp_path):
68+
mock_openai_model.return_value = MagicMock()
69+
config = _make_config(tmp_path)
70+
model = create_model(config)
71+
72+
mock_openai_model.assert_called_once_with(
73+
model_name="gpt-4",
74+
api_key="test-key",
75+
base_url="http://localhost:8000",
76+
)
77+
assert model is mock_openai_model.return_value
78+
79+
80+
class TestCreateWorkerAgent:
81+
82+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.preload_memory_tool", new_callable=lambda: MagicMock)
83+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WebFetchTool")
84+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WebSearchTool")
85+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ExecTool")
86+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ListDirTool")
87+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.EditFileTool")
88+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WriteFileTool")
89+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ReadFileTool")
90+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.LlmAgent")
91+
def test_returns_agent_with_tools(
92+
self,
93+
mock_llm_agent,
94+
mock_read,
95+
mock_write,
96+
mock_edit,
97+
mock_listdir,
98+
mock_exec,
99+
mock_web_search,
100+
mock_web_fetch,
101+
mock_preload,
102+
tmp_path,
103+
):
104+
config = _make_config(tmp_path)
105+
model = MagicMock()
106+
mock_llm_agent.return_value = MagicMock()
107+
108+
result = create_worker_agent(config, model)
109+
110+
mock_llm_agent.assert_called_once()
111+
call_kwargs = mock_llm_agent.call_args
112+
assert call_kwargs[1]["name"] == "trpc-claw-py_worker"
113+
assert len(call_kwargs[1]["tools"]) == 8
114+
assert result is mock_llm_agent.return_value
115+
116+
117+
class TestCreateAgent:
118+
119+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.build_mcp_toolsets", return_value=[])
120+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.create_skill_tool_set")
121+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ClawPrompts")
122+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.preload_memory_tool", new_callable=lambda: MagicMock)
123+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.SpawnTaskTool")
124+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.MessageTool")
125+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WebFetchTool")
126+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WebSearchTool")
127+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ExecTool")
128+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ListDirTool")
129+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.EditFileTool")
130+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WriteFileTool")
131+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ReadFileTool")
132+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.LlmAgent")
133+
def test_returns_agent_with_tools(
134+
self,
135+
mock_llm_agent,
136+
mock_read,
137+
mock_write,
138+
mock_edit,
139+
mock_listdir,
140+
mock_exec,
141+
mock_web_search,
142+
mock_web_fetch,
143+
mock_message,
144+
mock_spawn,
145+
mock_preload,
146+
mock_prompts_cls,
147+
mock_skill_tool_set,
148+
mock_build_mcp,
149+
tmp_path,
150+
):
151+
config = _make_config(tmp_path)
152+
model = MagicMock()
153+
worker = MagicMock()
154+
155+
mock_prompts_instance = MagicMock()
156+
mock_prompts_instance.build_system_prompt.return_value = "system prompt"
157+
mock_prompts_cls.return_value = mock_prompts_instance
158+
159+
mock_skill_ts = MagicMock()
160+
mock_skill_ts.repository = MagicMock()
161+
mock_skill_tool_set.return_value = mock_skill_ts
162+
163+
mock_llm_agent.return_value = MagicMock()
164+
165+
result = create_agent(config, model, worker_agent=worker)
166+
167+
mock_llm_agent.assert_called_once()
168+
call_kwargs = mock_llm_agent.call_args[1]
169+
assert call_kwargs["name"] == "trpc-claw-py"
170+
assert call_kwargs["sub_agents"] == [worker]
171+
assert call_kwargs["skill_repository"] is mock_skill_ts.repository
172+
assert result is mock_llm_agent.return_value
173+
174+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.build_mcp_toolsets", return_value=[])
175+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.create_skill_tool_set")
176+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ClawPrompts")
177+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.preload_memory_tool", new_callable=lambda: MagicMock)
178+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.SpawnTaskTool")
179+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.MessageTool")
180+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WebFetchTool")
181+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WebSearchTool")
182+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ExecTool")
183+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ListDirTool")
184+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.EditFileTool")
185+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WriteFileTool")
186+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ReadFileTool")
187+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.LlmAgent")
188+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.CronTool")
189+
def test_with_cron_service(
190+
self,
191+
mock_cron_tool,
192+
mock_llm_agent,
193+
mock_read,
194+
mock_write,
195+
mock_edit,
196+
mock_listdir,
197+
mock_exec,
198+
mock_web_search,
199+
mock_web_fetch,
200+
mock_message,
201+
mock_spawn,
202+
mock_preload,
203+
mock_prompts_cls,
204+
mock_skill_tool_set,
205+
mock_build_mcp,
206+
tmp_path,
207+
):
208+
config = _make_config(tmp_path)
209+
model = MagicMock()
210+
cron = MagicMock()
211+
worker = MagicMock()
212+
213+
mock_prompts_instance = MagicMock()
214+
mock_prompts_instance.build_system_prompt.return_value = "prompt"
215+
mock_prompts_cls.return_value = mock_prompts_instance
216+
217+
mock_skill_ts = MagicMock()
218+
mock_skill_ts.repository = MagicMock()
219+
mock_skill_tool_set.return_value = mock_skill_ts
220+
221+
mock_llm_agent.return_value = MagicMock()
222+
223+
create_agent(config, model, cron_service=cron, worker_agent=worker)
224+
225+
mock_cron_tool.assert_called_once_with(cron_service=cron)
226+
227+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.build_mcp_toolsets", return_value=[])
228+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.create_skill_tool_set")
229+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ClawPrompts")
230+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.preload_memory_tool", new_callable=lambda: MagicMock)
231+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.SpawnTaskTool")
232+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.MessageTool")
233+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WebFetchTool")
234+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WebSearchTool")
235+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ExecTool")
236+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ListDirTool")
237+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.EditFileTool")
238+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.WriteFileTool")
239+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.ReadFileTool")
240+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.LlmAgent")
241+
@patch("trpc_agent_sdk.server.openclaw.agent._agent.create_worker_agent")
242+
def test_creates_default_worker_when_none_provided(
243+
self,
244+
mock_create_worker,
245+
mock_llm_agent,
246+
mock_read,
247+
mock_write,
248+
mock_edit,
249+
mock_listdir,
250+
mock_exec,
251+
mock_web_search,
252+
mock_web_fetch,
253+
mock_message,
254+
mock_spawn,
255+
mock_preload,
256+
mock_prompts_cls,
257+
mock_skill_tool_set,
258+
mock_build_mcp,
259+
tmp_path,
260+
):
261+
config = _make_config(tmp_path)
262+
model = MagicMock()
263+
264+
mock_prompts_instance = MagicMock()
265+
mock_prompts_instance.build_system_prompt.return_value = "prompt"
266+
mock_prompts_cls.return_value = mock_prompts_instance
267+
268+
mock_skill_ts = MagicMock()
269+
mock_skill_ts.repository = MagicMock()
270+
mock_skill_tool_set.return_value = mock_skill_ts
271+
272+
mock_llm_agent.return_value = MagicMock()
273+
mock_create_worker.return_value = MagicMock()
274+
275+
create_agent(config, model)
276+
277+
mock_create_worker.assert_called_once()

0 commit comments

Comments
 (0)