Testing Suite Overview
The SmartPi Assistant includes a comprehensive automated testing suite to verify all system components function correctly. The test suite covers device firmware, bridge server, and end-to-end integration testing.
Test Philosophy
Our testing approach follows a bottom-up strategy, starting with the hardware endpoints and progressively testing higher-level abstractions:
- Device Level — Test Raspberry Pi Pico W HTTP endpoints directly
- Bridge Level — Verify MCP bridge server functionality
- Integration Level — Test n8n workflow and LLM integration
- System Level — Validate complete end-to-end data flow
Test Scripts
🔌 test_pico_endpoint.py
Purpose: Tests the Raspberry Pi Pico W device endpoints directly
What it tests:
- Device network reachability
- Status endpoint (
/status) - Message posting (single and batch)
- Theme variations (calendar, email, weather, slack, neutral)
- Priority sorting (urgent, important, normal)
- Message text wrapping for 64×64 display
- Queue clearing (
/clear) - Error handling and timeout behavior
Requirements:
- SmartPi device powered on and connected to WiFi
- Python 3.8+ with
requestslibrary - Correct device IP address
Usage:
# Install requirements
pip install requests
# Update IP in script (default: 192.168.1.100)
python test_pico_endpoint.py
# Or pass IP as argument
python test_pico_endpoint.py 192.168.1.230Expected Output:
SmartPi Pico W Endpoint Test Suite
Device URL: http://192.168.1.100
Note: Watch the SmartPi display during tests
Testing: Device Reachability
✓ Device is reachable at http://192.168.1.100
Testing: Single Message
✓ Single message posted successfully
⚠ Check SmartPi display to verify message appears
Testing: Batch Messages
✓ Batch of 3 messages posted successfully
Testing: Theme Variations
✓ All 5 themes tested successfully
Testing: Priority Sorting
✓ Messages sorted by priority correctly
...
Total: 9/9 tests passed
All tests passed! ✓🌉 test_bridge.py
Purpose: Tests the MCP Bridge Server functionality
What it tests:
- Bridge server health and availability
- MCP manifest endpoint (
/.well-known/mcp.json) - MCP tool calls (
push_messages,get_status,clear_queue) - Direct push endpoint (
/push) - Error handling and retry logic
- Connection to SmartPi device
Requirements:
- Bridge server must be running (
python smartpi_mcp_server.py) - Python 3.8+ with
requestslibrary - SmartPi device accessible from bridge
Usage:
# Install requirements
pip install requests
# Run tests (default: http://localhost:5055)
python test_bridge.py
# Test bridge at different URL
python test_bridge.py http://192.168.1.50:5055Expected Output:
Testing: Bridge Health Check
✓ Bridge is healthy
Bridge: online
Device: http://192.168.1.100 (reachable)
Testing: MCP Manifest Endpoint
✓ Manifest returned successfully
Tools available: 3
Testing: MCP Tool: push_messages
✓ Messages pushed successfully
Message count: 2
Device response: ok
Testing: Direct Push Endpoint
✓ Direct push successful
...
Total: 7/7 tests passed
All tests passed! ✓💻 test_smartpi.sh
Purpose: Quick shell script for manual testing
What it does:
- Checks device status
- Sends test message
- Sends themed messages (calendar, email, weather)
- Uses
curlfor simple HTTP testing
Requirements:
curlcommand availablepython3for JSON pretty-printing- SmartPi device accessible
Usage:
# Update PICO_IP in script first
./test_smartpi.sh
# Or edit inline
PICO_IP="192.168.1.100:5000" bash test_smartpi.shSystem Setup & Configuration
Prerequisites
- Hardware: Assembled SmartPi with Raspberry Pi Pico W, LED matrix, and power supply
- Network: WiFi network with DHCP (for Pico W)
- Software: Python 3.8+, pip, git
- Accounts: n8n Cloud account (or self-hosted n8n), Google Gemini API key
Configuration Steps
Device Setup
Flash CircuitPython firmware to Pico W and configure WiFi credentials in secrets.py
secrets = {
"ssid": "YourWiFi",
"password": "password"
}Bridge Server
Install dependencies and configure environment variables
pip install -r requirements.txt
# Create .env file
SMARTPI_DEVICE_URL=http://192.168.1.100Network Tunnel
Start ngrok tunnel for cloud-to-local communication
ngrok http 5055
# Note the https URL
# e.g. https://abc123.ngrok-free.appn8n Workflow
Import workflow and configure HTTP Request node with ngrok URL
# In n8n HTTP Request node:
URL: https://abc123.ngrok-free.app/mcp
Method: POSTTesting Strategy
Test components in this order to isolate issues efficiently:
Recommended Testing Order
- Device First — Verify Pico W is responsive
python test_pico_endpoint.py 192.168.1.100 - Bridge Second — Test bridge can communicate with device
python test_bridge.py - n8n Third — Execute workflow manually in n8n UI
- Check execution logs for errors
- Verify HTTP Request node returns 200 OK
- Full System Last — Schedule workflow and verify automated execution
- Wait for scheduled execution
- Check SmartPi display updates
- Verify message rotation every 5 seconds
Troubleshooting Guide
Device Test Failures
| Error | Cause | Solution |
|---|---|---|
| "Cannot connect to device" | Network connectivity issue |
• Verify device is powered on • Check WiFi connection via serial console • Ping device: ping 192.168.1.100• Verify IP address is correct |
| "Connection timed out" | Slow network or device |
• Increase TEST_TIMEOUT value in script• Check WiFi signal strength • Verify HTTP server is running on Pico |
| "Messages not displaying" | Display hardware or firmware issue |
• Check serial console for errors • Verify CircuitPython is running • Check LED matrix connections • Test with simple color fill program |
Bridge Test Failures
| Error | Cause | Solution |
|---|---|---|
| "Cannot connect to bridge" | Bridge server not running |
• Check if bridge is running: ps aux | grep smartpi• Verify port 5055 is open: lsof -i :5055• Start bridge: python smartpi_mcp_server.py
|
| "Device unreachable" | Bridge can't reach Pico |
• Check SMARTPI_DEVICE_URL in .env file• Test direct connection: curl http://192.168.1.100/status• Verify both bridge and device are on same network |
| "Tool calls fail" | JSON format or payload issue |
• Check bridge logs for details • Verify JSON payload format • Test with direct push endpoint first |
Production Deployment
Running as a Service
For production deployments, run the bridge server as a systemd service:
# Create service file: /etc/systemd/system/smartpi-bridge.service
[Unit]
Description=SmartPi MCP Bridge Server
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/smartpi
Environment="PATH=/home/pi/smartpi/venv/bin"
ExecStart=/home/pi/smartpi/venv/bin/python smartpi_mcp_server.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
# Enable and start service
sudo systemctl enable smartpi-bridge
sudo systemctl start smartpi-bridge
# Check status
sudo systemctl status smartpi-bridgeContinuous Monitoring
Set up automated testing to monitor system health:
#!/bin/bash
# monitor.sh - Run tests periodically
while true; do
echo "=== Test run at $(date) ===" >> test_results.log
python test_pico_endpoint.py 192.168.1.100 >> test_results.log 2>&1
python test_bridge.py >> test_results.log 2>&1
# Alert on failure
if [ $? -ne 0 ]; then
echo "Tests failed!" | mail -s "SmartPi Alert" your@email.com
fi
sleep 3600 # Run every hour
doneBackup and Recovery
Important Files to Backup
code.py— Pico W firmwaresecrets.py— WiFi credentials.env— Bridge configurationn8n-workflow.json— Workflow export- Bridge server code and dependencies
Backup command:
tar -czf smartpi-backup-$(date +%Y%m%d).tar.gz \
code.py secrets.py .env n8n-workflow.json \
smartpi_mcp_server.py requirements.txtPerformance Testing
Load Testing
Test device behavior under concurrent requests:
#!/usr/bin/env python3
import requests
import time
import concurrent.futures
PICO_URL = "http://192.168.1.100"
def send_message(i):
payload = {
"messages": [{"text": f"Load test {i}", "theme": "neutral"}]
}
try:
response = requests.post(
f"{PICO_URL}/messages",
json=payload,
timeout=5
)
return response.status_code == 200
except:
return False
# Send 100 requests with 10 concurrent workers
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(send_message, range(100)))
success_rate = sum(results) / len(results) * 100
print(f"Success rate: {success_rate:.1f}%")
print(f"Failed requests: {len(results) - sum(results)}")Performance Metrics
| Component | Metric | Typical Value |
|---|---|---|
| SmartPi Device | Response Time | < 100ms |
| SmartPi Device | Display Refresh Rate | 60 FPS |
| MCP Bridge | Latency (local) | < 50ms |
| Google Gemini LLM | Summarization Time | ~2 seconds |
| End-to-End | Workflow to Display | 3-5 seconds |
| Message Rotation | Interval | 5 seconds |
Additional Resources
Documentation Links
- Complete README.md — Full project documentation
- Software Architecture — Detailed system design
- Hardware Design — PCB and component details
- Test Suite README — Testing documentation