Spaces:
Paused
Paused
Yuga Planner Test Framework Instructions
Overview
This document provides instructions for writing, running, and maintaining tests in the Yuga Planner project using our standardized test framework.
Quick Start
Running Tests
Standard Testing (recommended for CI/CD)
pytest tests/test_*.py -v
Debug Mode (detailed output for troubleshooting)
YUGA_DEBUG=true pytest tests/test_*.py -v -s
Direct Execution (individual test files)
python tests/test_specific_file.py
YUGA_DEBUG=true python tests/test_specific_file.py # with debug output
Writing Tests
1. Basic Test Structure
Every test file should follow this pattern:
import sys
from tests.test_utils import get_test_logger, create_test_results
# Initialize logging
logger = get_test_logger(__name__)
def test_your_feature():
"""Test function that works with both pytest and direct execution."""
logger.start_test("Description of what you're testing")
try:
# Your test logic here
result = your_function_to_test()
# Use assertions for validation
assert result is not None, "Result should not be None"
assert result.status == "success", f"Expected success, got {result.status}"
logger.pass_test("Feature works correctly")
except Exception as e:
logger.fail_test(f"Test failed: {str(e)}")
raise
# Direct execution support
if __name__ == "__main__":
results = create_test_results(logger)
results.run_test('test_your_feature', test_your_feature)
all_passed = results.summary()
sys.exit(0 if all_passed else 1)
2. Test Utilities Reference
TestLogger Methods
from tests.test_utils import get_test_logger
logger = get_test_logger(__name__)
# Test lifecycle
logger.start_test("Test description") # Mark test beginning
logger.pass_test("Success message") # Log successful completion
logger.fail_test("Error message") # Log test failure
# Organization
logger.section("Section Title") # Create visual separators
# Standard logging levels
logger.debug("Detailed debug information")
logger.info("General information")
logger.warning("Warning message")
logger.error("Error message")
TestResults Methods
from tests.test_utils import create_test_results
results = create_test_results(logger)
# Run tests with automatic error handling
results.run_test('test_name', test_function)
# Generate summary and get overall result
all_passed = results.summary() # Returns True if all tests passed
# Use for exit codes
sys.exit(0 if all_passed else 1)
3. Async Test Pattern
For async tests, use this pattern:
import asyncio
import pytest
@pytest.mark.asyncio
async def test_async_feature():
"""Async test that works with pytest."""
logger.start_test("Testing async functionality")
try:
result = await your_async_function()
assert result.is_valid(), "Async result should be valid"
logger.pass_test("Async functionality works")
except Exception as e:
logger.fail_test(f"Async test failed: {str(e)}")
raise
# For direct execution of async tests
async def run_async_tests():
"""Helper for running async tests directly."""
logger.section("Async Tests")
await test_async_feature()
if __name__ == "__main__":
results = create_test_results(logger)
# Use asyncio.run for async test execution
results.run_test('async_tests', lambda: asyncio.run(run_async_tests()))
all_passed = results.summary()
sys.exit(0 if all_passed else 1)
4. Complex Test Files
For files with multiple test functions:
def test_feature_one():
logger.start_test("Testing feature one")
# ... test logic ...
logger.pass_test("Feature one works")
def test_feature_two():
logger.start_test("Testing feature two")
# ... test logic ...
logger.pass_test("Feature two works")
def test_integration():
logger.start_test("Testing integration")
# ... test logic ...
logger.pass_test("Integration works")
if __name__ == "__main__":
results = create_test_results(logger)
# Run all tests
results.run_test('feature_one', test_feature_one)
results.run_test('feature_two', test_feature_two)
results.run_test('integration', test_integration)
# Generate summary
all_passed = results.summary()
sys.exit(0 if all_passed else 1)
Environment Control
Debug Output Control
The framework respects the YUGA_DEBUG
environment variable:
YUGA_DEBUG=false
or unset: Minimal output suitable for CI/CDYUGA_DEBUG=true
: Detailed debug output for troubleshooting
Usage Examples
# Quiet mode (default)
pytest tests/test_factory.py -v
# Debug mode
YUGA_DEBUG=true pytest tests/test_factory.py -v -s
# Direct execution with debug
YUGA_DEBUG=true python tests/test_constraints.py
Best Practices
1. Test Organization
- Use descriptive test function names:
test_calendar_event_creation_with_constraints
- Group related tests in the same file
- Use
logger.section()
to separate different test groups within a file
2. Error Messages
- Always provide clear assertion messages:
assert result.count == 5, f"Expected 5 items, got {result.count}"
3. Test Lifecycle
- Always use
logger.start_test()
at the beginning of each test - Use
logger.pass_test()
orlogger.fail_test()
to mark completion - Let exceptions propagate for pytest compatibility
4. Output Structure
- Use sections to organize output:
logger.section("Calendar Operations Tests") # ... run calendar tests ... logger.section("Task Management Tests") # ... run task tests ...
Integration with Existing Code
Pytest Compatibility
The framework is fully compatible with existing pytest features:
- Test discovery works without changes
- Fixtures continue to work normally
- Async tests work with
@pytest.mark.asyncio
- All pytest command-line options are supported
Logging Integration
- Integrates with project's
utils.logging_config
- Respects existing logging configuration
- No interference with application logging
Troubleshooting
Common Issues
- Tests run but no output: Ensure you're using
-s
flag with pytest in debug mode - Import errors: Make sure
tests/test_utils.py
is accessible - Async tests failing: Use
@pytest.mark.asyncio
for pytest,asyncio.run()
for direct execution
Debug Mode Benefits
When YUGA_DEBUG=true
:
- Detailed function entry/exit logging
- Variable state information
- Extended error messages
- Test timing information
Example Test Files
Refer to these existing test files for patterns:
tests/test_calendar_operations.py
- Basic synchronous teststests/test_task_composer_agent.py
- Async test patternstests/test_constraints.py
- Large pytest-based test suitetests/test_factory.py
- Complex test file with multiple test types
Summary
This test framework provides:
- Consistency across all test files
- Flexibility for different execution modes
- Professional output suitable for development and CI/CD
- Maintainability through centralized utilities
- Compatibility with existing pytest workflows
Follow these patterns for all new tests to maintain consistency and leverage the full power of the test framework.