Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[tool:pytest]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Wrong INI section header — pytest will ignore this file.

In pytest.ini the section must be [pytest], not [tool:pytest].

Apply:

-[tool:pytest]
+[pytest]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
[tool:pytest]
File: pytest.ini
[pytest]
🤖 Prompt for AI Agents
In pytest.ini around line 1, the INI section header is incorrect: change the
section header from "[tool:pytest]" to "[pytest]" so pytest will recognize and
load the configuration; update that single line accordingly and keep the rest of
the file intact.

# Pytest configuration for LightSpeed Evaluation Framework

# Test discovery
testpaths = tests
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_*

# Output options
addopts =
-v
--tb=short
--strict-markers
--disable-warnings
--color=yes

# Markers
markers =
integration: Integration tests that require real config files
slow: Tests that take a long time to run
unit: Fast unit tests
config: Configuration-related tests
metrics: Metric evaluation tests
output: Output generation tests

Comment on lines +18 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Unregistered marker used by suite and runner ("cli").

With --strict-markers enabled, -m cli will error unless registered.

Apply:

 markers =
     integration: Integration tests that require real config files
     slow: Tests that take a long time to run
     unit: Fast unit tests
     config: Configuration-related tests
     metrics: Metric evaluation tests
     output: Output generation tests
+    cli: CLI-related tests
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Markers
markers =
integration: Integration tests that require real config files
slow: Tests that take a long time to run
unit: Fast unit tests
config: Configuration-related tests
metrics: Metric evaluation tests
output: Output generation tests
# Markers
markers =
integration: Integration tests that require real config files
slow: Tests that take a long time to run
unit: Fast unit tests
config: Configuration-related tests
metrics: Metric evaluation tests
output: Output generation tests
cli: CLI-related tests
🤖 Prompt for AI Agents
In pytest.ini around lines 18 to 26, the test suite uses an unregistered pytest
marker "cli" which causes failures when --strict-markers is enabled; add a new
marker entry for "cli" under the markers list (e.g., add a line like "cli:
Command-line interface tests") so the marker is registered and the -m cli
selection and runner no longer error.

# Minimum version
minversion = 6.0

# Test timeout (in seconds)
timeout = 300
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

timeout requires pytest-timeout plugin — verify availability.

If pytest-timeout isn’t installed, this option is ignored.

Run:


🏁 Script executed:

#!/bin/bash
python - <<'PY'
import importlib.util as u
print("pytest-timeout installed:", bool(u.find_spec("pytest_timeout")))
PY

Length of output: 42


Install pytest-timeout plugin – the timeout = 300 setting in pytest.ini (line 31) is ignored without it (pytest-timeout not detected).

🤖 Prompt for AI Agents
In pytest.ini around line 31, the timeout = 300 setting is ignored because the
pytest-timeout plugin is not installed; add pytest-timeout to the project's
test/dev dependencies (e.g. requirements-dev.txt, pyproject.toml/poetry, or
Pipfile), update the lockfile, and run the package install so pytest can detect
the plugin and honor the timeout setting; optionally verify by running pytest -q
to confirm the timeout plugin appears in the collected plugins list.


# Coverage options (if pytest-cov is installed)
# addopts = --cov=lightspeed_evaluation --cov-report=html --cov-report=term-missing

# Ignore certain warnings
filterwarnings =
ignore::DeprecationWarning
ignore::PendingDeprecationWarning
ignore::UserWarning:matplotlib.*
ignore::UserWarning:seaborn.*
287 changes: 287 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
# LightSpeed Evaluation Framework - Test Suite

This directory contains comprehensive tests for the LightSpeed Evaluation Framework. The test suite covers all major components and provides both unit and integration tests.

## Test Structure

```
tests/
├── README.md # This file
├── conftest.py # Pytest configuration and shared fixtures
├── run_tests.py # Test runner script for convenient test execution
├── test_evaluation.py # Main evaluation tests
├── test_config.py # Configuration loading and validation tests
├── test_metrics.py # Metrics evaluation tests
└── test_cli.py # Command-line interface tests
```

## Test Categories

The tests are organized into several categories using pytest markers:

### By Component
- **`config`**: Configuration loading, validation, and environment setup
- **`metrics`**: Metric evaluation (Ragas, DeepEval, Custom)
- **`cli`**: Command-line interface and argument parsing
- **`output`**: Report generation and output handling

### By Type
- **`unit`**: Fast unit tests with mocked dependencies
- **`integration`**: Integration tests using real configuration files
- **`slow`**: Tests that take longer to run (usually integration tests)

## Running Tests

### Prerequisites

Install the required testing dependencies:

```bash
pip install pytest pytest-cov
```

### Basic Usage

```bash
# Run all tests
python -m pytest tests/

# Run with verbose output
python -m pytest tests/ -v

# Run specific test file
python -m pytest tests/test_config.py

# Run specific test class
python -m pytest tests/test_config.py::TestSystemConfig

# Run specific test method
python -m pytest tests/test_config.py::TestSystemConfig::test_system_config_defaults
```

### Using the Test Runner Script

The project includes a convenient test runner script located in the `tests/` directory:

```bash
# Run all tests
python tests/run_tests.py

# Run only unit tests
python tests/run_tests.py --type unit

# Run only integration tests
python tests/run_tests.py --type integration

# Run tests by component
python tests/run_tests.py --type config
python tests/run_tests.py --type metrics
python tests/run_tests.py --type cli

# Run with coverage report
python tests/run_tests.py --coverage

# Run with verbose output
python tests/run_tests.py --verbose

# Run fast tests only (exclude slow tests)
python tests/run_tests.py --type fast

# Run specific test file
python tests/run_tests.py test_config.py

# Custom markers
python tests/run_tests.py --markers "unit and not slow"
```

### Test Markers

Use pytest markers to run specific test categories:

```bash
# Run only unit tests
python -m pytest -m unit

# Run only integration tests
python -m pytest -m integration

# Run config-related tests
python -m pytest -m config

# Run metrics-related tests
python -m pytest -m metrics

# Run CLI-related tests
python -m pytest -m cli

# Exclude slow tests
python -m pytest -m "not slow"

# Combine markers
python -m pytest -m "unit and config"
```

## Test Configuration

### Environment Variables

The tests automatically set up required environment variables:

- `OPENAI_API_KEY`: Set to a test value for mocking
- `DEEPEVAL_TELEMETRY_OPT_OUT`: Disabled for testing
- `LITELLM_LOG_LEVEL`: Set to ERROR to reduce noise

### Fixtures

The test suite provides several useful fixtures in `conftest.py`:

- **`sample_system_config`**: Pre-configured SystemConfig object
- **`sample_llm_config`**: Pre-configured LLMConfig object
- **`sample_turn_data`**: Sample conversation turn data
- **`sample_evaluation_data`**: Complete evaluation data structure
- **`mock_llm_manager`**: Mocked LLM manager for testing
- **`temp_config_files`**: Temporary configuration files
- **`temp_output_dir`**: Temporary output directory

## Test Coverage

To generate a coverage report:

```bash
# Generate HTML coverage report
python -m pytest --cov=lightspeed_evaluation --cov-report=html tests/

# Generate terminal coverage report
python -m pytest --cov=lightspeed_evaluation --cov-report=term-missing tests/

# Using the test runner
python tests/run_tests.py --coverage
```

The HTML coverage report will be generated in `htmlcov/index.html`.

## Writing New Tests

### Test File Organization

- **Unit tests**: Test individual functions/classes with mocked dependencies
- **Integration tests**: Test component interactions with real or realistic data
- **Use descriptive test names**: `test_load_system_config_with_valid_file`
- **Group related tests**: Use test classes to organize related functionality

### Example Test Structure

```python
class TestMyComponent:
"""Test MyComponent functionality."""

def test_basic_functionality(self):
"""Test basic functionality with valid input."""
# Arrange
component = MyComponent()

# Act
result = component.do_something()

# Assert
assert result is not None

def test_error_handling(self):
"""Test error handling with invalid input."""
component = MyComponent()

with pytest.raises(ValueError, match="Expected error message"):
component.do_something_invalid()

@pytest.mark.integration
def test_integration_scenario(self):
"""Test integration with other components."""
# Integration test code here
pass
```

### Using Fixtures

```python
def test_with_fixtures(sample_system_config, temp_output_dir):
"""Test using provided fixtures."""
# Use the fixtures in your test
assert sample_system_config.llm_provider == "openai"
assert Path(temp_output_dir).exists()
```

### Mocking External Dependencies

```python
@patch('lightspeed_evaluation.core.metrics.ragas.evaluate')
def test_with_mocked_dependency(mock_evaluate):
"""Test with mocked external dependency."""
# Configure mock
mock_evaluate.return_value = MagicMock()

# Run test
result = my_function_that_uses_ragas()

# Verify mock was called
mock_evaluate.assert_called_once()
```

## Continuous Integration

The test suite is designed to work in CI environments:

- All external dependencies are mocked
- Temporary files are properly cleaned up
- Tests are deterministic and don't rely on external services
- Environment variables are properly managed

## Troubleshooting

### Common Issues

1. **Import Errors**: Make sure the package is installed in development mode:
```bash
pip install -e .
```

2. **Missing Dependencies**: Install test dependencies:
```bash
pip install pytest pytest-cov
```

3. **Configuration File Tests**: Some tests require the actual config files to exist:
- `config/system.yaml`
- `config/evaluation_data.yaml`

4. **Environment Variables**: Tests automatically set required environment variables, but you can override them if needed.

### Debug Mode

Run tests with more verbose output for debugging:

```bash
python -m pytest tests/ -v -s --tb=long
```

### Running Individual Tests

For debugging specific tests:

```bash
# Run a specific test with full output
python -m pytest tests/test_config.py::TestSystemConfig::test_system_config_defaults -v -s

# Run with pdb debugger on failure
python -m pytest tests/test_config.py --pdb
```

## Contributing

When adding new functionality:

1. Write tests for new features
2. Ensure good test coverage (aim for >90%)
3. Use appropriate markers for test categorization
4. Mock external dependencies
5. Add integration tests for complex workflows
6. Update this README if adding new test categories or patterns
Loading
Loading