# Synqed Test Suite

Comprehensive test suite for the Synqed package.

## Test Structure

```
tests/
├── conftest.py              # Pytest fixtures and configuration
├── test_agent.py            # Unit tests for Agent class
├── test_agent_card.py       # Unit tests for AgentCardBuilder
├── test_server.py           # Unit tests for AgentServer
├── test_client.py           # Unit tests for Client
├── test_delegator.py        # Unit tests for TaskDelegator
├── test_integration.py      # Integration tests
└── test_e2e.py             # End-to-end tests
```

## Running Tests

### Run All Tests
```bash
pytest
```

### Run Specific Test File
```bash
pytest tests/test_agent.py
```

### Run Specific Test Class
```bash
pytest tests/test_agent.py::TestAgent
```

### Run Specific Test Method
```bash
pytest tests/test_agent.py::TestAgent::test_agent_creation_with_simple_skills
```

### Run with Coverage
```bash
pytest --cov=src/synqed --cov-report=html
```

### Run Only Unit Tests
```bash
pytest tests/test_agent.py tests/test_agent_card.py tests/test_server.py tests/test_client.py tests/test_delegator.py
```

### Run Only Integration Tests
```bash
pytest tests/test_integration.py -m integration
```

### Run Only E2E Tests
```bash
pytest tests/test_e2e.py -m e2e
```

### Run with Verbose Output
```bash
pytest -v
```

### Run with Debug Output
```bash
pytest -vv --tb=long
```

## Test Categories

### Unit Tests
Test individual components in isolation:
- **test_agent.py**: Agent creation, configuration, executors
- **test_agent_card.py**: Card building, skills, capabilities
- **test_server.py**: Server lifecycle, configuration
- **test_client.py**: Client connections, messaging
- **test_delegator.py**: Agent registration, task routing

### Integration Tests (test_integration.py)
Test components working together:
- Agent + Server + Client flow
- Multi-agent delegation
- Card propagation
- Concurrent requests
- Skill-based routing

### End-to-End Tests (test_e2e.py)
Test complete real-world scenarios:
- Simple conversations
- Multi-agent collaboration
- Dynamic routing
- Streaming responses
- Error handling
- Complete workflows

## Writing New Tests

### Unit Test Template
```python
class TestYourComponent:
    """Tests for YourComponent."""
    
    def test_basic_functionality(self):
        """Test basic functionality."""
        # Arrange
        component = YourComponent()
        
        # Act
        result = component.do_something()
        
        # Assert
        assert result == expected_value
    
    @pytest.mark.asyncio
    async def test_async_functionality(self):
        """Test async functionality."""
        component = YourComponent()
        result = await component.do_something_async()
        assert result is not None
```

### Integration Test Template
```python
@pytest.mark.asyncio
async def test_component_integration(self, fixture1, fixture2):
    """Test components working together."""
    # Set up components
    comp1 = Component1(fixture1)
    comp2 = Component2(fixture2)
    
    # Test interaction
    result = await comp1.interact_with(comp2)
    
    # Verify
    assert result.is_valid()
```

### E2E Test Template
```python
@pytest.mark.asyncio
async def test_complete_workflow(self, port_generator):
    """Test complete user workflow."""
    # Step 1: Set up system
    agent = create_agent()
    server = start_server(agent, port_generator())
    
    try:
        # Step 2: User interaction
        client = connect_client(server.url)
        result = await client.do_something()
        
        # Step 3: Verify outcome
        assert result.success
    finally:
        # Cleanup
        await server.stop()
```

## Fixtures

Common fixtures available in `conftest.py`:

- `simple_agent`: Basic test agent
- `recipe_agent`: Agent with cooking skills
- `weather_agent`: Agent with weather skills
- `simple_server`: Running server with simple agent
- `recipe_server`: Running server with recipe agent
- `weather_server`: Running server with weather agent
- `port_generator`: Generates unique ports for tests

## Best Practices

1. **Isolation**: Each test should be independent
2. **Cleanup**: Always clean up resources (servers, clients)
3. **Async**: Use `@pytest.mark.asyncio` for async tests
4. **Fixtures**: Reuse fixtures from conftest.py
5. **Naming**: Use descriptive test names (test_what_when_then)
6. **Documentation**: Add docstrings to tests
7. **Assertions**: Use specific, meaningful assertions
8. **Coverage**: Aim for >90% code coverage

## Continuous Integration

Tests are designed to run in CI/CD pipelines:

```yaml
# Example GitHub Actions
- name: Run tests
  run: |
    pip install -e ".[dev]"
    pytest --cov=src/synqed --cov-report=xml
```

## Troubleshooting

### Port Conflicts
If tests fail with "Address already in use":
```bash
# Use port_generator fixture
# Or run tests sequentially
pytest -n 1
```

### Slow Tests
Mark slow tests:
```python
@pytest.mark.slow
def test_slow_operation():
    ...

# Skip slow tests
pytest -m "not slow"
```

### Async Issues
Ensure pytest-asyncio is installed:
```bash
pip install pytest-asyncio
```

## Coverage Reports

After running tests with coverage:
```bash
# View HTML report
open htmlcov/index.html

# View terminal report
pytest --cov=src/synqed --cov-report=term
```

## Performance Testing

For performance tests (not included by default):
```bash
pytest --durations=10  # Show 10 slowest tests
```

