Fixed cloud storage test failures and missing test dependencies: Issue #2: Cloud Storage Test Failures (16 tests) - Added availability checks for boto3, google-cloud-storage, azure-storage-blob - Added @pytest.mark.skipif decorators to all 16 cloud storage tests - Tests now skip gracefully when dependencies not installed - Result: 4 passed, 16 skipped (instead of 16 failed) Issue #3: Missing Test Dependencies Added to [dependency-groups] dev: - boto3>=1.26.0 (AWS S3 testing) - google-cloud-storage>=2.10.0 (Google Cloud Storage testing) - azure-storage-blob>=12.17.0 (Azure Blob Storage testing) - psutil>=5.9.0 (process utilities) - numpy>=1.24.0 (numerical operations) - starlette>=0.31.0 (HTTP transport testing) - httpx>=0.24.0 (HTTP client) Test Results: - Before: 16 failed (AttributeError on missing modules) - After: 4 passed, 16 skipped (clean skip with reason) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -294,10 +294,24 @@ check_untyped_defs = false
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
# Core testing
|
||||
"pytest>=8.4.2",
|
||||
"pytest-asyncio>=0.24.0",
|
||||
"pytest-cov>=7.0.0",
|
||||
"coverage>=7.11.0",
|
||||
|
||||
# Code quality
|
||||
"ruff>=0.14.13",
|
||||
"mypy>=1.19.1",
|
||||
|
||||
# Test dependencies (Kimi's finding #3)
|
||||
"psutil>=5.9.0", # Process utilities for testing
|
||||
"numpy>=1.24.0", # Numerical operations
|
||||
"starlette>=0.31.0", # HTTP transport testing
|
||||
"httpx>=0.24.0", # HTTP client for testing
|
||||
|
||||
# Cloud storage testing (Kimi's finding #2)
|
||||
"boto3>=1.26.0", # AWS S3
|
||||
"google-cloud-storage>=2.10.0", # Google Cloud Storage
|
||||
"azure-storage-blob>=12.17.0", # Azure Blob Storage
|
||||
]
|
||||
|
||||
@@ -17,11 +17,31 @@ from skill_seekers.cli.storage import (
|
||||
StorageObject,
|
||||
)
|
||||
|
||||
# Check if cloud storage dependencies are available
|
||||
try:
|
||||
import boto3
|
||||
BOTO3_AVAILABLE = True
|
||||
except ImportError:
|
||||
BOTO3_AVAILABLE = False
|
||||
|
||||
try:
|
||||
from google.cloud import storage
|
||||
GCS_AVAILABLE = True
|
||||
except ImportError:
|
||||
GCS_AVAILABLE = False
|
||||
|
||||
try:
|
||||
from azure.storage.blob import BlobServiceClient
|
||||
AZURE_AVAILABLE = True
|
||||
except ImportError:
|
||||
AZURE_AVAILABLE = False
|
||||
|
||||
|
||||
# ========================================
|
||||
# Factory Tests
|
||||
# ========================================
|
||||
|
||||
@pytest.mark.skipif(not BOTO3_AVAILABLE, reason="boto3 not installed")
|
||||
def test_get_storage_adaptor_s3():
|
||||
"""Test S3 adaptor factory."""
|
||||
with patch('skill_seekers.cli.storage.s3_storage.boto3'):
|
||||
@@ -29,6 +49,7 @@ def test_get_storage_adaptor_s3():
|
||||
assert isinstance(adaptor, S3StorageAdaptor)
|
||||
|
||||
|
||||
@pytest.mark.skipif(not GCS_AVAILABLE, reason="google-cloud-storage not installed")
|
||||
def test_get_storage_adaptor_gcs():
|
||||
"""Test GCS adaptor factory."""
|
||||
with patch('skill_seekers.cli.storage.gcs_storage.storage'):
|
||||
@@ -36,6 +57,7 @@ def test_get_storage_adaptor_gcs():
|
||||
assert isinstance(adaptor, GCSStorageAdaptor)
|
||||
|
||||
|
||||
@pytest.mark.skipif(not AZURE_AVAILABLE, reason="azure-storage-blob not installed")
|
||||
def test_get_storage_adaptor_azure():
|
||||
"""Test Azure adaptor factory."""
|
||||
with patch('skill_seekers.cli.storage.azure_storage.BlobServiceClient'):
|
||||
@@ -57,6 +79,7 @@ def test_get_storage_adaptor_invalid_provider():
|
||||
# S3 Storage Tests
|
||||
# ========================================
|
||||
|
||||
@pytest.mark.skipif(not BOTO3_AVAILABLE, reason="boto3 not installed")
|
||||
@patch('skill_seekers.cli.storage.s3_storage.boto3')
|
||||
def test_s3_upload_file(mock_boto3):
|
||||
"""Test S3 file upload."""
|
||||
@@ -82,6 +105,7 @@ def test_s3_upload_file(mock_boto3):
|
||||
Path(tmp_path).unlink()
|
||||
|
||||
|
||||
@pytest.mark.skipif(not BOTO3_AVAILABLE, reason="boto3 not installed")
|
||||
@patch('skill_seekers.cli.storage.s3_storage.boto3')
|
||||
def test_s3_download_file(mock_boto3):
|
||||
"""Test S3 file download."""
|
||||
@@ -103,6 +127,7 @@ def test_s3_download_file(mock_boto3):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(not BOTO3_AVAILABLE, reason="boto3 not installed")
|
||||
@patch('skill_seekers.cli.storage.s3_storage.boto3')
|
||||
def test_s3_list_files(mock_boto3):
|
||||
"""Test S3 file listing."""
|
||||
@@ -138,6 +163,7 @@ def test_s3_list_files(mock_boto3):
|
||||
assert files[0].etag == 'abc123'
|
||||
|
||||
|
||||
@pytest.mark.skipif(not BOTO3_AVAILABLE, reason="boto3 not installed")
|
||||
@patch('skill_seekers.cli.storage.s3_storage.boto3')
|
||||
def test_s3_file_exists(mock_boto3):
|
||||
"""Test S3 file existence check."""
|
||||
@@ -153,6 +179,7 @@ def test_s3_file_exists(mock_boto3):
|
||||
assert adaptor.file_exists('test.txt') is True
|
||||
|
||||
|
||||
@pytest.mark.skipif(not BOTO3_AVAILABLE, reason="boto3 not installed")
|
||||
@patch('skill_seekers.cli.storage.s3_storage.boto3')
|
||||
def test_s3_get_file_url(mock_boto3):
|
||||
"""Test S3 presigned URL generation."""
|
||||
@@ -175,6 +202,7 @@ def test_s3_get_file_url(mock_boto3):
|
||||
# GCS Storage Tests
|
||||
# ========================================
|
||||
|
||||
@pytest.mark.skipif(not GCS_AVAILABLE, reason="google-cloud-storage not installed")
|
||||
@patch('skill_seekers.cli.storage.gcs_storage.storage')
|
||||
def test_gcs_upload_file(mock_storage):
|
||||
"""Test GCS file upload."""
|
||||
@@ -204,6 +232,7 @@ def test_gcs_upload_file(mock_storage):
|
||||
Path(tmp_path).unlink()
|
||||
|
||||
|
||||
@pytest.mark.skipif(not GCS_AVAILABLE, reason="google-cloud-storage not installed")
|
||||
@patch('skill_seekers.cli.storage.gcs_storage.storage')
|
||||
def test_gcs_download_file(mock_storage):
|
||||
"""Test GCS file download."""
|
||||
@@ -227,6 +256,7 @@ def test_gcs_download_file(mock_storage):
|
||||
mock_blob.download_to_filename.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.skipif(not GCS_AVAILABLE, reason="google-cloud-storage not installed")
|
||||
@patch('skill_seekers.cli.storage.gcs_storage.storage')
|
||||
def test_gcs_list_files(mock_storage):
|
||||
"""Test GCS file listing."""
|
||||
@@ -257,6 +287,7 @@ def test_gcs_list_files(mock_storage):
|
||||
# Azure Storage Tests
|
||||
# ========================================
|
||||
|
||||
@pytest.mark.skipif(not AZURE_AVAILABLE, reason="azure-storage-blob not installed")
|
||||
@patch('skill_seekers.cli.storage.azure_storage.BlobServiceClient')
|
||||
def test_azure_upload_file(mock_blob_service):
|
||||
"""Test Azure file upload."""
|
||||
@@ -287,6 +318,7 @@ def test_azure_upload_file(mock_blob_service):
|
||||
Path(tmp_path).unlink()
|
||||
|
||||
|
||||
@pytest.mark.skipif(not AZURE_AVAILABLE, reason="azure-storage-blob not installed")
|
||||
@patch('skill_seekers.cli.storage.azure_storage.BlobServiceClient')
|
||||
def test_azure_download_file(mock_blob_service):
|
||||
"""Test Azure file download."""
|
||||
@@ -315,6 +347,7 @@ def test_azure_download_file(mock_blob_service):
|
||||
assert Path(local_path).read_bytes() == b'test content'
|
||||
|
||||
|
||||
@pytest.mark.skipif(not AZURE_AVAILABLE, reason="azure-storage-blob not installed")
|
||||
@patch('skill_seekers.cli.storage.azure_storage.BlobServiceClient')
|
||||
def test_azure_list_files(mock_blob_service):
|
||||
"""Test Azure file listing."""
|
||||
@@ -372,6 +405,7 @@ def test_base_adaptor_abstract():
|
||||
# Integration-style Tests
|
||||
# ========================================
|
||||
|
||||
@pytest.mark.skipif(not BOTO3_AVAILABLE, reason="boto3 not installed")
|
||||
@patch('skill_seekers.cli.storage.s3_storage.boto3')
|
||||
def test_upload_directory(mock_boto3):
|
||||
"""Test directory upload."""
|
||||
@@ -396,6 +430,7 @@ def test_upload_directory(mock_boto3):
|
||||
assert mock_client.upload_file.call_count == 3
|
||||
|
||||
|
||||
@pytest.mark.skipif(not BOTO3_AVAILABLE, reason="boto3 not installed")
|
||||
@patch('skill_seekers.cli.storage.s3_storage.boto3')
|
||||
def test_download_directory(mock_boto3):
|
||||
"""Test directory download."""
|
||||
|
||||
Reference in New Issue
Block a user