DevOps Agent Testing Guide
This document provides comprehensive information about the testing infrastructure and practices for the DevOps Agent project.
๐ Test Structure
The test suite is organized into a clear hierarchy under the tests/
directory:
tests/
โโโ __init__.py # Test package initialization
โโโ conftest.py # Pytest configuration and fixtures
โโโ pytest.ini # Pytest settings
โโโ unit/ # Unit tests for individual components
โ โโโ __init__.py
โ โโโ test_state_management.py # StateManager and TurnState tests
โ โโโ test_retry_logic.py # Error classification and retry tests
โโโ integration/ # Integration tests for component interactions
โ โโโ __init__.py
โ โโโ test_agent_lifecycle.py # Complete agent execution flow tests
โโโ e2e/ # End-to-end tests for complete workflows
โ โโโ __init__.py
โโโ fixtures/ # Test data and utilities
โโโ __init__.py
โโโ test_helpers.py # Common test utilities and fixtures
โโโ mock_data.py # Sample data for testing
โโโ mock_tools.py # Mock tool implementations
โโโ mock_llm.py # Mock LLM client for testing
๐งช Test Categories
Unit Tests (tests/unit/
)
Test individual components and functions in isolation:
- State Management: Tests for
StateManager
,TurnState
, and related classes - Retry Logic: Tests for error classification and retry mechanisms
- Context Optimization: Tests for context reduction strategies
- Validation: Tests for input validation and error handling
Integration Tests (tests/integration/
)
Test interactions between different components:
- Agent Lifecycle: Tests for complete agent execution cycles
- Tool Integration: Tests for tool execution and state updates
- Context Flow: Tests for context management across turns
- Planning Integration: Tests for planning manager integration
End-to-End Tests (tests/e2e/
)
Test complete workflows and user scenarios:
- Conversation Flows: Tests for complete conversation scenarios
- Error Recovery: Tests for error handling and recovery workflows
- Performance: Tests for performance and resource usage
- Real-World Scenarios: Tests for realistic usage patterns
๐ ๏ธ Running Tests
Prerequisites
Install testing dependencies using uv
:
# Install pytest and related packages
uv add --dev pytest pytest-asyncio pytest-mock pytest-cov
# Install the project in development mode
uv pip install -e .
Basic Test Execution
# Run all tests
uv run pytest
# Run tests with verbose output
uv run pytest -v
# Run specific test categories
uv run pytest -m unit # Unit tests only
uv run pytest -m integration # Integration tests only
uv run pytest -m e2e # End-to-end tests only
# Run specific test files
uv run pytest tests/unit/test_state_management.py
uv run pytest tests/integration/test_agent_lifecycle.py
# Run specific test functions
uv run pytest tests/unit/test_state_management.py::TestStateManager::test_start_new_turn
Advanced Test Options
# Run tests with coverage reporting
uv run pytest --cov=agents.devops --cov-report=html --cov-report=term-missing
# Run tests in parallel (if pytest-xdist is installed)
uv run pytest -n auto
# Run only failed tests from last run
uv run pytest --lf
# Run tests and stop on first failure
uv run pytest -x
# Run tests with detailed output for debugging
uv run pytest -vvv --tb=long
# Run async tests only
uv run pytest -m async_test
๐ง Test Configuration
Pytest Configuration (pytest.ini
)
The test suite is configured with:
- Test Discovery: Automatic discovery of test files and functions
- Markers: Custom markers for categorizing tests
- Async Support: Automatic handling of async test functions
- Timeout Protection: 5-minute timeout for long-running tests
- Warning Filters: Suppression of known harmless warnings
Fixtures and Utilities
Common fixtures are available in conftest.py
:
state_manager
: Fresh StateManager instancepopulated_state_manager
: StateManager with sample datamock_agent
: Mock DevOps agent for testingmock_llm_request/response
: Mock LLM interactionstest_metrics
: Metrics collection for performance testing
Test Helpers
The tests/fixtures/test_helpers.py
module provides:
- Mock classes for all major components
- Sample data generators
- Assertion helpers for validation
- Performance measurement utilities
๐ Test Coverage
Current Coverage Areas
The test suite covers:
โ State Management (Comprehensive)
- StateManager class functionality
- TurnState validation and lifecycle
- Legacy state format compatibility
- Concurrent access protection
- Error handling and recovery
โ Retry Logic (Comprehensive)
- Error classification (retryable vs non-retryable)
- Context optimization strategies
- Exponential backoff with jitter
- Circuit breaker mechanisms
- Timeout protection
โ Agent Lifecycle (Integration)
- Complete conversation turns
- Tool execution flow
- State persistence across turns
- Error recovery mechanisms
- Performance characteristics
Coverage Goals
Target coverage levels:
- Unit Tests: >95% line coverage
- Integration Tests: >90% feature coverage
- E2E Tests: >80% workflow coverage
๐ Writing New Tests
Unit Test Example
import pytest
from devops_agent import StateManager, TurnPhase
class TestNewFeature:
def setup_method(self):
self.state_manager = StateManager()
def test_new_functionality(self):
# Arrange
turn = self.state_manager.start_new_turn("Test message")
# Act
result = self.state_manager.some_new_method()
# Assert
assert result is not None
assert turn.phase == TurnPhase.PROCESSING_USER_INPUT
Integration Test Example
import pytest
from tests.fixtures.test_helpers import MockCallbackContext, create_sample_legacy_state
class TestNewIntegration:
@pytest.mark.asyncio
async def test_component_interaction(self):
# Setup
agent = MyDevopsAgent(name="test", model="test")
context = MockCallbackContext(create_sample_legacy_state())
# Test interaction
result = await agent.handle_some_interaction(context)
# Verify
assert result is not None
Best Practices
- Use Descriptive Names: Test names should clearly describe what is being tested
- Follow AAA Pattern: Arrange, Act, Assert for clear test structure
- Mock External Dependencies: Use mocks for LLM calls, file operations, etc.
- Test Error Conditions: Include tests for error scenarios and edge cases
- Use Fixtures: Leverage existing fixtures for common setup
- Add Markers: Use appropriate markers (
@pytest.mark.unit
, etc.)
๐ Debugging Tests
Common Issues
- Async Test Failures: Ensure
@pytest.mark.asyncio
is used for async tests - State Pollution: Use fresh fixtures to avoid test interdependencies
- Mock Issues: Verify mocks are properly configured and reset
- Timeout Errors: Check for infinite loops or hanging operations
Debugging Tools
# Run with Python debugger
uv run pytest --pdb
# Run with detailed logging
uv run pytest --log-cli-level=DEBUG
# Run single test with maximum verbosity
uv run pytest -vvv --tb=long tests/path/to/test.py::test_function
๐ Performance Testing
Metrics Collection
Use the TestMetrics
helper for performance testing:
def test_performance(test_metrics):
start_time = time.time()
# Perform operation
result = expensive_operation()
duration = time.time() - start_time
test_metrics.record_operation("expensive_operation", duration)
# Assert performance requirements
assert duration < 1.0 # Should complete in under 1 second
Memory Testing
def test_memory_usage():
import sys
initial_size = sys.getsizeof(object_under_test)
# Perform operations that might increase memory
for i in range(1000):
object_under_test.add_data(f"item_{i}")
final_size = sys.getsizeof(object_under_test)
growth_ratio = final_size / initial_size
# Assert reasonable memory growth
assert growth_ratio < 10 # Less than 10x growth
๐ Continuous Integration
GitHub Actions Integration
The test suite is designed to work with CI/CD pipelines:
# Example GitHub Actions workflow
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install uv
run: pip install uv
- name: Install dependencies
run: uv sync --dev
- name: Run tests
run: uv run pytest --cov=agents.devops --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v3
Pre-commit Hooks
Consider adding pre-commit hooks for automatic test execution:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: pytest-unit
name: pytest-unit
entry: uv run pytest -m unit
language: system
pass_filenames: false
๐ Additional Resources
- Pytest Documentation: https://docs.pytest.org/
- Pytest-asyncio: https://pytest-asyncio.readthedocs.io/
- Python Testing Best Practices: https://docs.python-guide.org/writing/tests/
- Mock Documentation: https://docs.python.org/3/library/unittest.mock.html
๐ค Contributing Tests
When contributing new features:
- Write Tests First: Consider TDD approach for new functionality
- Update Existing Tests: Modify tests when changing existing behavior
- Add Integration Tests: Ensure new features work with existing components
- Document Test Cases: Add comments explaining complex test scenarios
- Run Full Suite: Verify all tests pass before submitting PR
Last Updated: December 24, 2024
Test Coverage: Unit (95%), Integration (90%), E2E (80%)
Total Tests: 50+ test cases across all categories