|
1 | 1 | """ |
2 | | -Sample tests for AgentEx ACP agent. |
| 2 | +Tests for example-tutorial (OpenAI Agents SDK Hello World) |
3 | 3 |
|
4 | | -This test suite demonstrates how to test the main AgentEx API functions: |
5 | | -- Non-streaming event sending and polling |
6 | | -- Streaming event sending |
| 4 | +Prerequisites: |
| 5 | + - AgentEx services running (make dev) |
| 6 | + - Temporal server running |
| 7 | + - Agent running: agentex agents run --manifest manifest.yaml |
7 | 8 |
|
8 | | -To run these tests: |
9 | | -1. Make sure the agent is running (via docker-compose or `agentex agents run`) |
10 | | -2. Set the AGENTEX_API_BASE_URL environment variable if not using default |
11 | | -3. Run: pytest test_agent.py -v |
12 | | -
|
13 | | -Configuration: |
14 | | -- AGENTEX_API_BASE_URL: Base URL for the AgentEx server (default: http://localhost:5003) |
15 | | -- AGENT_NAME: Name of the agent to test (default: example-tutorial) |
| 9 | +Run: pytest tests/test_agent.py -v |
16 | 10 | """ |
17 | 11 |
|
18 | | -import os |
19 | | -import uuid |
20 | | - |
21 | 12 | import pytest |
22 | | -import pytest_asyncio |
23 | | -from test_utils.async_utils import ( |
24 | | - poll_messages, |
25 | | - send_event_and_poll_yielding, |
26 | | -) |
27 | | - |
28 | | -from agentex import AsyncAgentex |
29 | | -from agentex.types.task_message import TaskMessage |
30 | | -from agentex.types.agent_rpc_params import ParamsCreateTaskRequest |
31 | | - |
32 | | -# Configuration from environment variables |
33 | | -AGENTEX_API_BASE_URL = os.environ.get("AGENTEX_API_BASE_URL", "http://localhost:5003") |
34 | | -AGENT_NAME = os.environ.get("AGENT_NAME", "at060-open-ai-agents-sdk-hello-world") |
35 | | - |
36 | 13 |
|
37 | | -@pytest_asyncio.fixture |
38 | | -async def client(): |
39 | | - """Create an AsyncAgentex client instance for testing.""" |
40 | | - client = AsyncAgentex(base_url=AGENTEX_API_BASE_URL) |
41 | | - yield client |
42 | | - await client.close() |
| 14 | +from agentex.lib.testing import async_test_agent, assert_valid_agent_response |
43 | 15 |
|
| 16 | +AGENT_NAME = "example-tutorial" |
44 | 17 |
|
45 | | -@pytest.fixture |
46 | | -def agent_name(): |
47 | | - """Return the agent name for testing.""" |
48 | | - return AGENT_NAME |
49 | 18 |
|
| 19 | +@pytest.mark.asyncio |
| 20 | +async def test_agent_basic(): |
| 21 | + """Test basic agent functionality.""" |
| 22 | + async with async_test_agent(agent_name=AGENT_NAME) as test: |
| 23 | + response = await test.send_event("Test message", timeout_seconds=60.0) |
| 24 | + assert_valid_agent_response(response) |
50 | 25 |
|
51 | | -@pytest_asyncio.fixture |
52 | | -async def agent_id(client, agent_name): |
53 | | - """Retrieve the agent ID based on the agent name.""" |
54 | | - agents = await client.agents.list() |
55 | | - for agent in agents: |
56 | | - if agent.name == agent_name: |
57 | | - return agent.id |
58 | | - raise ValueError(f"Agent with name {agent_name} not found.") |
59 | 26 |
|
60 | | - |
61 | | -class TestNonStreamingEvents: |
62 | | - """Test non-streaming event sending and polling.""" |
63 | | - |
64 | | - @pytest.mark.asyncio |
65 | | - async def test_send_event_and_poll(self, client: AsyncAgentex, agent_id: str): |
66 | | - """Test sending an event and polling for the response.""" |
67 | | - task_response = await client.agents.create_task(agent_id, params=ParamsCreateTaskRequest(name=uuid.uuid1().hex)) |
68 | | - task = task_response.result |
69 | | - assert task is not None |
70 | | - |
71 | | - # Poll for the initial task creation message |
72 | | - async for message in poll_messages( |
73 | | - client=client, |
74 | | - task_id=task.id, |
75 | | - timeout=30, |
76 | | - sleep_interval=1.0, |
77 | | - ): |
78 | | - assert isinstance(message, TaskMessage) |
79 | | - if message.content and message.content.type == "text" and message.content.author == "agent": |
80 | | - # Check for the Haiku Assistant welcome message |
81 | | - assert "Haiku Assistant" in message.content.content |
82 | | - assert "Temporal" in message.content.content |
| 27 | +@pytest.mark.asyncio |
| 28 | +async def test_agent_streaming(): |
| 29 | + """Test streaming responses.""" |
| 30 | + async with async_test_agent(agent_name=AGENT_NAME) as test: |
| 31 | + events = [] |
| 32 | + async for event in test.send_event_and_stream("Stream test", timeout_seconds=60.0): |
| 33 | + events.append(event) |
| 34 | + if event.get("type") == "done": |
83 | 35 | break |
84 | | - |
85 | | - # Send event and poll for response with streaming updates |
86 | | - user_message = "Hello how is life?" |
87 | | - print(f"[DEBUG 060 POLL] Sending message: '{user_message}'") |
88 | | - |
89 | | - # Use yield_updates=True to get all streaming chunks as they're written |
90 | | - final_message = None |
91 | | - async for message in send_event_and_poll_yielding( |
92 | | - client=client, |
93 | | - agent_id=agent_id, |
94 | | - task_id=task.id, |
95 | | - user_message=user_message, |
96 | | - timeout=30, |
97 | | - sleep_interval=1.0, |
98 | | - yield_updates=True, # Get updates as streaming writes chunks |
99 | | - ): |
100 | | - if message.content and message.content.type == "text" and message.content.author == "agent": |
101 | | - print( |
102 | | - f"[DEBUG 060 POLL] Received update - Status: {message.streaming_status}, " |
103 | | - f"Content length: {len(message.content.content)}" |
104 | | - ) |
105 | | - final_message = message |
106 | | - |
107 | | - # Stop polling once we get a DONE message |
108 | | - if message.streaming_status == "DONE": |
109 | | - print(f"[DEBUG 060 POLL] Streaming complete!") |
110 | | - break |
111 | | - |
112 | | - # Verify the final message has content (the haiku) |
113 | | - assert final_message is not None, "Should have received an agent message" |
114 | | - assert final_message.content is not None, "Final message should have content" |
115 | | - assert len(final_message.content.content) > 0, "Final message should have haiku content" |
116 | | - |
117 | | - print(f"[DEBUG 060 POLL] ✅ Successfully received haiku response!") |
118 | | - print(f"[DEBUG 060 POLL] Final haiku:\n{final_message.content.content}") |
119 | | - pass |
120 | | - |
121 | | - |
122 | | -class TestStreamingEvents: |
123 | | - """Test streaming event sending (backend verification via polling).""" |
124 | | - |
125 | | - @pytest.mark.asyncio |
126 | | - async def test_send_event_and_stream(self, client: AsyncAgentex, agent_id: str): |
127 | | - """ |
128 | | - Streaming test placeholder. |
129 | | -
|
130 | | - NOTE: SSE streaming is tested via the UI (agentex-ui subscribeTaskState). |
131 | | - Backend streaming functionality is verified in test_send_event_and_poll. |
132 | | - """ |
133 | | - pass |
| 36 | + assert len(events) > 0 |
134 | 37 |
|
135 | 38 |
|
136 | 39 | if __name__ == "__main__": |
|
0 commit comments