Skip to content

Commit 80dee92

Browse files
bokelleyclaude
andauthored
feat: add test helpers for quick testing (#27)
* feat: add test helpers for easy testing and examples Added test helpers similar to the JavaScript client to provide pre-configured test agents for examples and quick testing: - test_agent: Pre-configured MCP test agent (ready to use) - test_agent_a2a: Pre-configured A2A test agent - test_agent_client: Multi-agent client with both protocols - create_test_agent(): Create custom test configurations New exports: - Available via 'from adcp.testing import ...' - Also exported from main adcp module Includes: - Full test coverage with 15 test cases - Comprehensive example script (test_helpers_demo.py) - Complete documentation in docstrings - Test helpers exported from main __init__.py Test agents are rate-limited and intended for testing/examples only. DO NOT use in production applications. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: add test helpers documentation to README Added comprehensive documentation for test helpers: - Quick Start section showcasing test helpers first - Dedicated Test Helpers feature section with examples - Clear warnings about rate limits and production use - Link to test_helpers_demo.py example Test helpers are now the recommended entry point for new users, making it easier to get started with AdCP without configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: organize imports to satisfy linter Moved test helper imports to proper location according to ruff's import sorting rules. Test helpers now imported after exceptions and before core types. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: remove unused imports and f-string prefix Removed unused pytest import from test_helpers.py and removed unnecessary f-string prefix from static string in demo script. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: remove invalid name field from AgentConfig AgentConfig doesn't have a 'name' field. Removed it from test agent configurations and updated tests/examples to use valid fields like 'timeout' instead. Also added type annotation (Any) for **overrides parameter in create_test_agent to satisfy mypy. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: update test to expect URI without trailing slash AgentConfig validator strips trailing slashes from URIs for consistency. Updated test expectation to match actual behavior. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add reference creative agent helper Added pre-configured creative_agent for easy access to the reference creative agent at creative.adcontextprotocol.org/mcp. This provides instant access to creative preview functionality without authentication. Features: - creative_agent: Pre-configured ADCPClient for creative operations - CREATIVE_AGENT_CONFIG: Exported configuration constant - No authentication required - Perfect for testing preview_creative and list_creative_formats Added 3 new tests for creative agent functionality and updated README with creative agent examples. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f16dca5 commit 80dee92

File tree

6 files changed

+745
-0
lines changed

6 files changed

+745
-0
lines changed

README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,41 @@ pip install adcp
2424

2525
> **Note**: This client requires Python 3.10 or later and supports both synchronous and asynchronous workflows.
2626
27+
## Quick Start: Test Helpers
28+
29+
The fastest way to get started is using the pre-configured test agents:
30+
31+
```python
32+
from adcp.testing import test_agent
33+
from adcp.types.generated import GetProductsRequest
34+
35+
# Zero configuration - just import and use!
36+
result = await test_agent.get_products(
37+
GetProductsRequest(
38+
brief="Coffee subscription service",
39+
promoted_offering="Premium coffee deliveries"
40+
)
41+
)
42+
43+
if result.success:
44+
print(f"Found {len(result.data.products)} products")
45+
```
46+
47+
Test helpers include:
48+
- **`test_agent`**: Pre-configured MCP test agent (ready to use)
49+
- **`test_agent_a2a`**: Pre-configured A2A test agent
50+
- **`creative_agent`**: Reference creative agent for preview functionality
51+
- **`test_agent_client`**: Multi-agent client with both protocols
52+
- **`create_test_agent()`**: Factory for custom test configurations
53+
54+
> **Note**: Test agents are rate-limited and for testing/examples only. DO NOT use in production.
55+
56+
See [examples/test_helpers_demo.py](examples/test_helpers_demo.py) for more examples.
57+
2758
## Quick Start: Distributed Operations
2859

60+
For production use, configure your own agents:
61+
2962
```python
3063
from adcp import ADCPMultiAgentClient, AgentConfig, GetProductsRequest
3164

@@ -75,6 +108,50 @@ async with ADCPMultiAgentClient(
75108

76109
## Features
77110

111+
### Test Helpers
112+
113+
Pre-configured test agents for instant prototyping and testing:
114+
115+
```python
116+
from adcp.testing import test_agent, test_agent_a2a, creative_agent, test_agent_client, create_test_agent
117+
from adcp.types.generated import GetProductsRequest, PreviewCreativeRequest
118+
119+
# 1. Single agent (MCP)
120+
result = await test_agent.get_products(
121+
GetProductsRequest(brief="Coffee brands")
122+
)
123+
124+
# 2. Single agent (A2A)
125+
result = await test_agent_a2a.get_products(
126+
GetProductsRequest(brief="Coffee brands")
127+
)
128+
129+
# 3. Creative agent (preview functionality)
130+
result = await creative_agent.preview_creative(
131+
PreviewCreativeRequest(
132+
manifest={"format_id": "banner_300x250", "assets": {...}}
133+
)
134+
)
135+
136+
# 4. Multi-agent (parallel execution)
137+
results = await test_agent_client.get_products(
138+
GetProductsRequest(brief="Coffee brands")
139+
)
140+
141+
# 5. Custom configuration
142+
from adcp.client import ADCPClient
143+
config = create_test_agent(id="my-test", timeout=60.0)
144+
client = ADCPClient(config)
145+
```
146+
147+
**Use cases:**
148+
- Quick prototyping and experimentation
149+
- Example code and documentation
150+
- Integration testing without mock servers
151+
- Learning AdCP concepts
152+
153+
**Important:** Test agents are public, rate-limited, and for testing only. Never use in production.
154+
78155
### Full Protocol Support
79156
- **A2A Protocol**: Native support for Agent-to-Agent protocol
80157
- **MCP Protocol**: Native support for Model Context Protocol

examples/test_helpers_demo.py

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
#!/usr/bin/env python3
2+
"""Test Helpers Demo - Using Pre-configured Test Agents.
3+
4+
This example shows how to use the built-in test helpers for quick testing and examples.
5+
"""
6+
7+
from __future__ import annotations
8+
9+
import asyncio
10+
11+
from adcp.client import ADCPMultiAgentClient
12+
from adcp.testing import (
13+
create_test_agent,
14+
test_agent,
15+
test_agent_a2a,
16+
test_agent_client,
17+
)
18+
from adcp.types.generated import GetProductsRequest, ListCreativeFormatsRequest
19+
20+
21+
async def simplest_example() -> None:
22+
"""Example 1: Simplest Possible Usage.
23+
24+
Use the pre-configured test agent directly - no setup needed!
25+
"""
26+
print("🎯 Example 1: Simplest Usage with test_agent")
27+
print("=" * 43)
28+
print()
29+
30+
try:
31+
# Just import and use - that's it!
32+
result = await test_agent.get_products(
33+
GetProductsRequest(
34+
brief="Premium coffee subscription service",
35+
promoted_offering="Artisan coffee deliveries",
36+
)
37+
)
38+
39+
if result.success and result.data:
40+
print(f"✅ Success! Found {len(result.data.products)} products")
41+
print(" Protocol: MCP")
42+
print()
43+
else:
44+
print(f"❌ Error: {result.error}")
45+
print()
46+
except Exception as e:
47+
print(f"❌ Network error: {e}")
48+
print()
49+
50+
51+
async def protocol_comparison() -> None:
52+
"""Example 2: Testing Both Protocols.
53+
54+
Use both A2A and MCP test agents to compare behavior.
55+
"""
56+
print("🔄 Example 2: Protocol Comparison (A2A vs MCP)")
57+
print("=" * 46)
58+
print()
59+
60+
request = GetProductsRequest(
61+
brief="Sustainable fashion brands",
62+
promoted_offering="Eco-friendly clothing",
63+
)
64+
65+
try:
66+
print("Testing MCP protocol...")
67+
mcp_result = await test_agent.get_products(request)
68+
print(f" MCP: {'✅' if mcp_result.success else '❌'}")
69+
70+
print("Testing A2A protocol...")
71+
a2a_result = await test_agent_a2a.get_products(request)
72+
print(f" A2A: {'✅' if a2a_result.success else '❌'}")
73+
print()
74+
except Exception as e:
75+
print(f"❌ Error: {e}")
76+
print()
77+
78+
79+
async def multi_agent_example() -> None:
80+
"""Example 3: Multi-Agent Testing.
81+
82+
Use the test_agent_client for parallel operations.
83+
"""
84+
print("🌐 Example 3: Multi-Agent Operations")
85+
print("=" * 36)
86+
print()
87+
88+
try:
89+
print(f"Testing with {len(test_agent_client.agent_ids)} agents in parallel...")
90+
91+
# Run the same query on both agents in parallel
92+
results = await test_agent_client.get_products(
93+
GetProductsRequest(
94+
brief="Tech gadgets for remote work",
95+
promoted_offering="Ergonomic workspace solutions",
96+
)
97+
)
98+
99+
print("\nResults:")
100+
for i, result in enumerate(results, 1):
101+
print(f" {i}. {'✅' if result.success else '❌'}")
102+
print()
103+
except Exception as e:
104+
print(f"❌ Error: {e}")
105+
print()
106+
107+
108+
async def custom_test_agent() -> None:
109+
"""Example 4: Custom Test Agent Configuration.
110+
111+
Create a custom test agent with modifications.
112+
"""
113+
print("⚙️ Example 4: Custom Test Agent Configuration")
114+
print("=" * 46)
115+
print()
116+
117+
# Create a custom config with your own ID
118+
custom_config = create_test_agent(
119+
id="my-custom-test",
120+
timeout=60.0,
121+
)
122+
123+
print("Created custom config:")
124+
print(f" ID: {custom_config.id}")
125+
print(f" Protocol: {custom_config.protocol}")
126+
print(f" URI: {custom_config.agent_uri}")
127+
print(f" Timeout: {custom_config.timeout}s")
128+
print()
129+
130+
# Use it with a client
131+
client = ADCPMultiAgentClient([custom_config])
132+
agent = client.agent("my-custom-test")
133+
134+
try:
135+
result = await agent.get_products(
136+
GetProductsRequest(
137+
brief="Travel packages",
138+
promoted_offering="European vacations",
139+
)
140+
)
141+
142+
print(f"Result: {'✅ Success' if result.success else '❌ Failed'}")
143+
print()
144+
except Exception as e:
145+
print(f"❌ Error: {e}")
146+
print()
147+
finally:
148+
await client.close()
149+
150+
151+
async def various_operations() -> None:
152+
"""Example 5: Testing Different Operations.
153+
154+
Show various ADCP operations with test agents.
155+
"""
156+
print("🎬 Example 5: Various ADCP Operations")
157+
print("=" * 37)
158+
print()
159+
160+
try:
161+
# Get products
162+
print("1. Getting products...")
163+
products = await test_agent.get_products(
164+
GetProductsRequest(
165+
brief="Coffee brands",
166+
promoted_offering="Premium coffee",
167+
)
168+
)
169+
success = "✅" if products.success else "❌"
170+
count = len(products.data.products) if products.data else 0
171+
print(f" {success} Products: {count}")
172+
173+
# List creative formats
174+
print("2. Listing creative formats...")
175+
formats = await test_agent.list_creative_formats(
176+
ListCreativeFormatsRequest()
177+
)
178+
success = "✅" if formats.success else "❌"
179+
count = len(formats.data.formats) if formats.data else 0
180+
print(f" {success} Formats: {count}")
181+
182+
print()
183+
except Exception as e:
184+
print(f"❌ Error: {e}")
185+
print()
186+
187+
188+
async def main() -> None:
189+
"""Main function - run all examples."""
190+
print("\n📚 ADCP Test Helpers - Demo Examples")
191+
print("=" * 37)
192+
print("These examples show how to use pre-configured test agents\n")
193+
194+
await simplest_example()
195+
await protocol_comparison()
196+
await multi_agent_example()
197+
await custom_test_agent()
198+
await various_operations()
199+
200+
print("💡 Key Takeaways:")
201+
print(" • test_agent = Pre-configured MCP test agent (ready to use!)")
202+
print(" • test_agent_a2a = Pre-configured A2A test agent")
203+
print(" • test_agent_client = Multi-agent client with both protocols")
204+
print(" • create_test_agent() = Create custom test configurations")
205+
print(" • Perfect for examples, docs, and quick testing")
206+
print("\n⚠️ Remember: Test agents are rate-limited and for testing only!")
207+
print(" DO NOT use in production applications.\n")
208+
209+
210+
if __name__ == "__main__":
211+
asyncio.run(main())

src/adcp/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818
ADCPWebhookError,
1919
ADCPWebhookSignatureError,
2020
)
21+
22+
# Test helpers
23+
from adcp.testing import (
24+
CREATIVE_AGENT_CONFIG,
25+
TEST_AGENT_A2A_CONFIG,
26+
TEST_AGENT_MCP_CONFIG,
27+
TEST_AGENT_TOKEN,
28+
create_test_agent,
29+
creative_agent,
30+
test_agent,
31+
test_agent_a2a,
32+
test_agent_client,
33+
)
2134
from adcp.types.core import AgentConfig, Protocol, TaskResult, TaskStatus, WebhookMetadata
2235
from adcp.types.generated import (
2336
ActivateSignalError,
@@ -145,6 +158,16 @@
145158
"TaskResult",
146159
"TaskStatus",
147160
"WebhookMetadata",
161+
# Test helpers
162+
"test_agent",
163+
"test_agent_a2a",
164+
"creative_agent",
165+
"test_agent_client",
166+
"create_test_agent",
167+
"TEST_AGENT_TOKEN",
168+
"TEST_AGENT_MCP_CONFIG",
169+
"TEST_AGENT_A2A_CONFIG",
170+
"CREATIVE_AGENT_CONFIG",
148171
# Exceptions
149172
"ADCPError",
150173
"ADCPConnectionError",

src/adcp/testing/__init__.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""Test helpers for AdCP client library.
2+
3+
Provides pre-configured test agents for examples and quick testing.
4+
"""
5+
6+
from __future__ import annotations
7+
8+
from adcp.testing.test_helpers import (
9+
CREATIVE_AGENT_CONFIG,
10+
TEST_AGENT_A2A_CONFIG,
11+
TEST_AGENT_MCP_CONFIG,
12+
TEST_AGENT_TOKEN,
13+
create_test_agent,
14+
creative_agent,
15+
test_agent,
16+
test_agent_a2a,
17+
test_agent_client,
18+
)
19+
20+
__all__ = [
21+
"test_agent",
22+
"test_agent_a2a",
23+
"creative_agent",
24+
"test_agent_client",
25+
"create_test_agent",
26+
"TEST_AGENT_TOKEN",
27+
"TEST_AGENT_MCP_CONFIG",
28+
"TEST_AGENT_A2A_CONFIG",
29+
"CREATIVE_AGENT_CONFIG",
30+
]

0 commit comments

Comments
 (0)