Testing Best Practices Guide
August 2, 2025 ยท View on GitHub
Quick Start
1. Use File-Based Output for All Tests
Do this:
from mcp_task_orchestrator.testing import TestOutputWriter
writer = TestOutputWriter(output_dir)
with writer.write_test_output("my_test", "text") as session:
session.write_line("Test output here...")
```text
**Not this:**
```text
text
python
print("Test output...")
# May be truncated
```text
text
#
#
# 2. Use Alternative Test Runners
**Do this:**
```text
python
from mcp_task_orchestrator.testing import DirectFunctionRunner
runner = DirectFunctionRunner(output_dir=Path("outputs"))
result = runner.execute_test(my_test_function, "test_name")
```text
text
**Not this:**
```text
bash
pytest my_test.py
# May have truncation issues
```text
text
#
#
# 3. Use Context Managers for Database Connections
**Do this:**
```text
python
from tests.utils.db_test_utils import managed_sqlite_connection
with managed_sqlite_connection("test.db") as conn:
# Work with connection
pass
# Automatic cleanup
```text
text
**Not this:**
```text
python
import sqlite3
conn = sqlite3.connect("test.db")
# Work with connection
conn.close()
# May not be called on exceptions
```text
text
#
#
# 4. Add Hang Protection
**Do this:**
```text
python
from mcp_task_orchestrator.monitoring.hang_detection import with_hang_detection
@with_hang_detection("my_operation", timeout=30.0)
async def my_operation():
# Protected operation
pass
```text
text
**Not this:**
```text
python
async def my_operation():
# Unprotected - may hang forever
pass
```text
text
#
# Common Patterns
#
#
# Testing Database Operations
```text
python
from tests.utils.db_test_utils import DatabaseTestCase
class MyTest(DatabaseTestCase):
def test_database_operation(self):
with self.get_managed_connection("test.db") as conn:
# Test database operations
pass
# Cleanup happens automatically
```text
#
#
# Testing Long-Running Operations
```text
python
from mcp_task_orchestrator.testing import TestOutputWriter
from mcp_task_orchestrator.monitoring.hang_detection import with_hang_detection
@with_hang_detection("long_test", timeout=60.0)
async def test_long_operation():
writer = TestOutputWriter(output_dir)
with writer.write_test_output("long_test", "text") as session:
session.write_line("Starting long operation...")
# Long operation here
session.write_line("Operation completed")
```text
#
#
# Safe Test Output Reading
```text
python
from mcp_task_orchestrator.testing import TestOutputReader
reader = TestOutputReader(output_dir)
output_file = find_latest_output_file("test_name")
if reader.wait_for_completion(output_file, timeout=30.0):
content = reader.read_completed_output(output_file)
# Process complete content
else:
print("Test did not complete within timeout")
```text
#
# Validation Checklist
Before deploying tests:
- [ ] Use file-based output for substantial output
- [ ] Add hang protection for operations > 10 seconds
- [ ] Use context managers for all database connections
- [ ] Test with alternative runners, not just pytest
- [ ] Validate no ResourceWarnings in test runs
- [ ] Ensure proper cleanup in test teardown
- [ ] Test timeout scenarios work correctly
#
# Quick Commands
```text
bash
# Test resource cleanup
python tests/test_resource_cleanup.py
# Test hang detection
python tests/test_hang_detection.py
# Demo file output system
python tests/demo_file_output_system.py
# Demo alternative runners
python tests/demo_alternative_runners.py
# Run enhanced migration test
python tests/enhanced_migration_test.py
```text
#
# Need Help?
- Check [TESTING_IMPROVEMENTS.md](TESTING_IMPROVEMENTS.md) for detailed documentation
- Review [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for common issues
- Examine test files in `tests/` directory for examples