Testing

View as MarkdownOpen in Claude

Testing Stages

1. Local Testing

  • Run agent locally
  • Test with swaig-test CLI
  • Verify SWML output

2. Tunnel Testing

  • Expose via ngrok
  • Make real calls
  • Test end-to-end

3. Production Testing

  • Deploy to production server
  • Test with real phone
  • Monitor call logs

swaig-test CLI

Test agents without making calls:

$# List available functions
$swaig-test my_agent.py --list-tools
$
$# View SWML output
$swaig-test my_agent.py --dump-swml
$
$# Execute a function
$swaig-test my_agent.py --exec get_weather --city Seattle
$
$# Raw JSON output
$swaig-test my_agent.py --dump-swml --raw

Local Server Testing

Run your agent locally using the appropriate command for your language:

LanguageStart Command
Pythonpython my_agent.py
TypeScriptnpx ts-node my_agent.ts

Then test the endpoint (the HTTP interface is identical regardless of language):

$# In another terminal, test the endpoint (use credentials from agent output or env vars)
$curl -X POST -u "$SWML_BASIC_AUTH_USER:$SWML_BASIC_AUTH_PASSWORD" http://localhost:3000/ \
> -H "Content-Type: application/json" \
> -d '{"call_id": "test-123"}'

Using ngrok

Expose local server for real calls:

$# Terminal 1: Run agent
$python my_agent.py
$
$# Terminal 2: Start ngrok
$ngrok http 3000

Copy the ngrok HTTPS URL and configure in SignalWire.

Test Call Checklist

Basic Functionality

  • Call connects successfully
  • Agent greeting plays
  • Speech recognition works
  • Agent responds appropriately

Function Calls

  • Functions execute correctly
  • Results returned to AI
  • AI summarizes results properly

Edge Cases

  • Silence handling
  • Interruption handling
  • Long responses
  • Multiple function calls

Error Handling

  • Invalid input handled
  • Function errors handled gracefully
  • Timeout behavior correct

Viewing Logs

In SignalWire dashboard:

  1. Go to Logs
  2. Find your test call
  3. View details:
    • Call duration
    • SWML executed
    • Function calls
    • Errors

Debugging with Logs

Add logging to your agent:

1import logging
2
3logging.basicConfig(level=logging.DEBUG)
4
5class MyAgent(AgentBase):
6 def __init__(self):
7 super().__init__(name="my-agent")
8 self.log.info("Agent initialized")
9
10 def my_handler(self, args, raw_data):
11 self.log.debug(f"Function called with args: {args}")
12 self.log.debug(f"Raw data: {raw_data}")
13
14 result = "Some result"
15 self.log.info(f"Returning: {result}")
16
17 return FunctionResult(result)

Testing Transfers

Test call transfers carefully. The transfer API is the same across languages via FunctionResult:

LanguageTransfer Call
PythonFunctionResult("Transferring").connect(number, final=True)
TypeScriptnew FunctionResult("Transferring").connect(number, { final: true })
1def test_transfer(self, args, raw_data):
2 # Use a test number you control
3 test_number = "+15551234567"
4
5 return (
6 FunctionResult("Transferring now")
7 .connect(test_number, final=True)
8 )

Testing SMS

Test SMS sending. The SMS API follows the same pattern across languages:

LanguageSend SMS
PythonFunctionResult("Sent").send_sms(to_number=to, from_number=from_, body=msg)
TypeScriptnew FunctionResult("Sent").sendSms({ toNumber: to, fromNumber: from, body: msg })
1def test_sms(self, args, raw_data):
2 # Send to your own phone for testing
3 return (
4 FunctionResult("Sent test SMS")
5 .send_sms(
6 to_number="+15551234567", # Your test phone
7 from_number="+15559876543", # Your SignalWire number
8 body="Test message from agent"
9 )
10 )

Load Testing

For production readiness:

  • Test concurrent call handling
  • Monitor server resources
  • Check response times under load
  • Verify function execution at scale
  • Test database/API connection pooling

Common Test Scenarios

ScenarioWhat to Test
Happy pathNormal conversation flow
No speechSilence and timeout handling
Background noiseSpeech recognition accuracy
Rapid speechInterruption handling
Invalid requestsError handling
Function errorsGraceful degradation
Long callsMemory and stability

Automated Testing

Create test scripts:

1import requests
2
3def test_swml_endpoint():
4 """Test that SWML endpoint returns valid response"""
5 response = requests.post(
6 "http://localhost:3000/",
7 json={"call_id": "test-123"},
8 headers={"Content-Type": "application/json"}
9 )
10
11 assert response.status_code == 200
12 data = response.json()
13 assert "version" in data
14 assert data["version"] == "1.0.0"
15
16def test_function_execution():
17 """Test that functions execute correctly"""
18 response = requests.post(
19 "http://localhost:3000/swaig",
20 json={
21 "function": "get_weather",
22 "argument": {"parsed": [{"city": "Seattle"}]},
23 "call_id": "test-123"
24 }
25 )
26
27 assert response.status_code == 200