Some checks failed
lint / docker (push) Has been cancelled
- Move all backup_*.py files to libtisbackup/drivers/ subdirectory - Move XenAPI.py and copy_vm_xcp.py to drivers/ (driver-specific) - Create drivers/__init__.py with automatic driver imports - Update tisbackup.py imports to use new structure - Add pyvmomi>=8.0.0 as mandatory dependency - Sync requirements.txt with pyproject.toml dependencies - Add pylint>=3.0.0 and pytest-cov>=6.0.0 to dev dependencies - Configure pylint and coverage tools in pyproject.toml - Add conventional commits guidelines to CLAUDE.md - Enhance .gitignore with comprehensive patterns for Python, IDEs, testing, and secrets - Update CLAUDE.md documentation with new structure and tooling Breaking Changes: - Drivers must now be imported from libtisbackup.drivers instead of libtisbackup - All backup driver files relocated to drivers/ subdirectory 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
3.0 KiB
3.0 KiB
TISBackup Test Suite
This directory contains the test suite for TISBackup using pytest.
Running Tests
Run all tests
uv run pytest
Run tests for a specific module
uv run pytest tests/test_ssh.py
Run with verbose output
uv run pytest -v
Run tests matching a pattern
uv run pytest -k "ssh" -v
Run with coverage (requires pytest-cov)
uv run pytest --cov=libtisbackup --cov-report=html
Test Structure
Current Test Modules
- test_ssh.py - Tests for SSH operations module
TestLoadSSHPrivateKey
- Tests for key loading with Ed25519, ECDSA, and RSA supportTestSSHExec
- Tests for remote command execution via SSHTestSSHModuleIntegration
- 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
uv run pytest -m unit
Run only SSH tests
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
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
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
@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:
- Test discovery patterns
- Output formatting
- Markers definition
- Minimum Python version
Continuous Integration
Tests should pass before merging:
# Run linting
uv run ruff check .
# Run tests
uv run pytest -v
# Both must pass