146 lines
3.0 KiB
Markdown
146 lines
3.0 KiB
Markdown
# TISBackup Test Suite
|
|||
|
|
|
||
|
|
This directory contains the test suite for TISBackup using pytest.
|
||
|
|
|
||
|
|
## Running Tests
|
||
|
|
|
||
|
|
### Run all tests
|
||
|
|
```bash
|
||
|
|
uv run pytest
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run tests for a specific module
|
||
|
|
```bash
|
||
|
|
uv run pytest tests/test_ssh.py
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run with verbose output
|
||
|
|
```bash
|
||
|
|
uv run pytest -v
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run tests matching a pattern
|
||
|
|
```bash
|
||
|
|
uv run pytest -k "ssh" -v
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run with coverage (requires pytest-cov)
|
||
|
|
```bash
|
||
|
|
uv run pytest --cov=libtisbackup --cov-report=html
|
||
|
|
```
|
||
|
|
|
||
|
|
## Test Structure
|
||
|
|
|
||
|
|
### Current Test Modules
|
||
|
|
|
||
|
|
- **[test_ssh.py](test_ssh.py)** - Tests for SSH operations module
|
||
|
|
- `TestLoadSSHPrivateKey` - Tests for key loading with Ed25519, ECDSA, and RSA support
|
||
|
|
- `TestSSHExec` - Tests for remote command execution via SSH
|
||
|
|
- `TestSSHModuleIntegration` - Integration tests for SSH functionality
|
||
|
|
|
||
|
|
## Test Categories
|
||
|
|
|
||
|
|
Tests are organized using pytest markers:
|
||
|
|
|
||
|
|
- `@pytest.mark.unit` - Unit tests for individual functions
|
||
|
|
- `@pytest.mark.integration` - Integration tests for multiple components
|
||
|
|
- `@pytest.mark.ssh` - SSH-related tests
|
||
|
|
- `@pytest.mark.slow` - Long-running tests
|
||
|
|
|
||
|
|
### Run only unit tests
|
||
|
|
```bash
|
||
|
|
uv run pytest -m unit
|
||
|
|
```
|
||
|
|
|
||
|
|
### Run only SSH tests
|
||
|
|
```bash
|
||
|
|
uv run pytest -m ssh
|
||
|
|
```
|
||
|
|
|
||
|
|
## Writing New Tests
|
||
|
|
|
||
|
|
### Test File Naming
|
||
|
|
- Test files should be named `test_*.py`
|
||
|
|
- Place them in the `tests/` directory
|
||
|
|
|
||
|
|
### Test Class Naming
|
||
|
|
- Test classes should start with `Test`
|
||
|
|
- Example: `TestMyModule`
|
||
|
|
|
||
|
|
### Test Function Naming
|
||
|
|
- Test functions should start with `test_`
|
||
|
|
- Use descriptive names: `test_load_ed25519_key_success`
|
||
|
|
|
||
|
|
### Example Test Structure
|
||
|
|
```python
|
||
|
|
import pytest
|
||
|
|
from libtisbackup.mymodule import my_function
|
||
|
|
|
||
|
|
class TestMyFunction:
|
||
|
|
"""Test cases for my_function."""
|
||
|
|
|
||
|
|
def test_basic_functionality(self):
|
||
|
|
"""Test basic use case."""
|
||
|
|
result = my_function("input")
|
||
|
|
assert result == "expected_output"
|
||
|
|
|
||
|
|
def test_error_handling(self):
|
||
|
|
"""Test error handling."""
|
||
|
|
with pytest.raises(ValueError):
|
||
|
|
my_function(None)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Mocking
|
||
|
|
|
||
|
|
The test suite uses `pytest-mock` for mocking dependencies. Common patterns:
|
||
|
|
|
||
|
|
### Mocking with patch
|
||
|
|
```python
|
||
|
|
from unittest.mock import patch, Mock
|
||
|
|
|
||
|
|
def test_with_mock():
|
||
|
|
with patch('module.function') as mock_func:
|
||
|
|
mock_func.return_value = "mocked"
|
||
|
|
result = my_code()
|
||
|
|
assert result == "mocked"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Using pytest fixtures
|
||
|
|
```python
|
||
|
|
@pytest.fixture
|
||
|
|
def mock_ssh_client():
|
||
|
|
return Mock(spec=paramiko.SSHClient)
|
||
|
|
|
||
|
|
def test_with_fixture(mock_ssh_client):
|
||
|
|
# Use the fixture
|
||
|
|
pass
|
||
|
|
```
|
||
|
|
|
||
|
|
## Coverage Goals
|
||
|
|
|
||
|
|
Aim for:
|
||
|
|
- **80%+** overall code coverage
|
||
|
|
- **90%+** for critical modules (ssh, database, base_driver)
|
||
|
|
- **100%** for utility functions
|
||
|
|
|
||
|
|
## Test Configuration
|
||
|
|
|
||
|
|
Test configuration is in the `[tool.pytest.ini_options]` section of [pyproject.toml](../pyproject.toml):
|
||
|
|
- Test discovery patterns
|
||
|
|
- Output formatting
|
||
|
|
- Markers definition
|
||
|
|
- Minimum Python version
|
||
|
|
|
||
|
|
## Continuous Integration
|
||
|
|
|
||
|
|
Tests should pass before merging:
|
||
|
|
```bash
|
||
|
|
# Run linting
|
||
|
|
uv run ruff check .
|
||
|
|
|
||
|
|
# Run tests
|
||
|
|
uv run pytest -v
|
||
|
|
|
||
|
|
# Both must pass
|
||
|
|
```
|