Skip to content
Open
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
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,39 @@ venv.bak/
models
logs
evaluation/evaluation_data

# Testing artifacts
.pytest_cache/
.coverage
.coverage.*
htmlcov/
coverage.xml
*.cover
.hypothesis/

# Claude settings
.claude/*

# Poetry
# Note: poetry.lock should be committed to version control

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store

# Build artifacts
*.egg-info/
dist/
build/
*.whl

# Virtual environments
venv/
.venv/
env/
.env/
virtualenv/
282 changes: 282 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
[tool.poetry]
name = "python-project"
version = "0.1.0"
description = "A Python project with comprehensive testing infrastructure"
authors = ["Your Name <your.email@example.com>"]
readme = "README.md"
license = "MIT"
packages = [{include = "." }]

[tool.poetry.dependencies]
python = "^3.8"

[tool.poetry.group.dev.dependencies]
pytest = "^8.3.4"
pytest-cov = "^5.0.0"
pytest-mock = "^3.14.0"


[tool.pytest.ini_options]
minversion = "8.0"
testpaths = [
"tests",
]
python_files = [
"test_*.py",
"*_test.py",
"tests.py",
]
python_classes = [
"Test*",
"*Tests",
]
python_functions = [
"test_*",
]
addopts = [
"-ra",
"--strict-markers",
"--strict-config",
"--cov=.",
"--cov-branch",
"--cov-report=term-missing:skip-covered",
"--cov-report=html:htmlcov",
"--cov-report=xml:coverage.xml",
"--tb=short",
"--maxfail=1",
]
markers = [
"unit: Unit tests",
"integration: Integration tests",
"slow: Tests that take more than a few seconds",
]
filterwarnings = [
"error",
"ignore::UserWarning",
"ignore::DeprecationWarning",
]

[tool.coverage.run]
source = ["."]
omit = [
"*/tests/*",
"*/__pycache__/*",
"*/venv/*",
"*/.venv/*",
"*/env/*",
"*/.env/*",
"*/virtualenv/*",
"*/site-packages/*",
"*/dist-packages/*",
"setup.py",
"*/migrations/*",
"*/__init__.py",
"*/conftest.py",
]

[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
"class .*\\bProtocol\\):",
"@(abc\\.)?abstractmethod",
]
precision = 2
show_missing = true
skip_covered = false
skip_empty = true
sort = "Cover"

[tool.coverage.html]
directory = "htmlcov"

[tool.coverage.xml]
output = "coverage.xml"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
Empty file added tests/__init__.py
Empty file.
148 changes: 148 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import json
import os
import shutil
import tempfile
from pathlib import Path
from typing import Generator, Dict, Any

import pytest


@pytest.fixture
def temp_dir() -> Generator[Path, None, None]:
"""Create a temporary directory for testing."""
temp_path = tempfile.mkdtemp()
yield Path(temp_path)
shutil.rmtree(temp_path, ignore_errors=True)


@pytest.fixture
def mock_config() -> Dict[str, Any]:
"""Provide a mock configuration dictionary."""
return {
"debug": True,
"verbose": False,
"batch_size": 32,
"learning_rate": 0.001,
"epochs": 10,
"output_dir": "/tmp/test_output",
"model_type": "test_model",
}


@pytest.fixture
def sample_data() -> Dict[str, Any]:
"""Provide sample data for testing."""
return {
"input": [1, 2, 3, 4, 5],
"output": [2, 4, 6, 8, 10],
"metadata": {
"version": "1.0",
"created": "2025-01-01",
"author": "test",
}
}


@pytest.fixture
def mock_json_file(temp_dir: Path, sample_data: Dict[str, Any]) -> Path:
"""Create a mock JSON file for testing."""
json_path = temp_dir / "test_data.json"
with open(json_path, "w") as f:
json.dump(sample_data, f)
return json_path


@pytest.fixture
def mock_text_file(temp_dir: Path) -> Path:
"""Create a mock text file for testing."""
text_path = temp_dir / "test_file.txt"
text_path.write_text("This is a test file.\nWith multiple lines.\n")
return text_path


@pytest.fixture
def mock_python_file(temp_dir: Path) -> Path:
"""Create a mock Python file for testing."""
py_path = temp_dir / "test_module.py"
py_path.write_text("""
def test_function(x: int) -> int:
return x * 2

class TestClass:
def __init__(self, value: int):
self.value = value

def method(self) -> int:
return self.value + 10
""")
return py_path


@pytest.fixture
def env_vars(monkeypatch) -> Dict[str, str]:
"""Set and manage environment variables for testing."""
test_vars = {
"TEST_ENV": "testing",
"DEBUG": "1",
"API_KEY": "test_key_123",
}

for key, value in test_vars.items():
monkeypatch.setenv(key, value)

return test_vars


@pytest.fixture(autouse=True)
def cleanup_test_files():
"""Automatically clean up any test files created during tests."""
yield
# Clean up patterns
patterns = ["test_*.tmp", "*.test", ".test_*"]
for pattern in patterns:
for file in Path.cwd().glob(pattern):
if file.is_file():
file.unlink(missing_ok=True)
elif file.is_dir():
shutil.rmtree(file, ignore_errors=True)


@pytest.fixture
def mock_image_file(temp_dir: Path) -> Path:
"""Create a mock image file path for testing."""
# Note: This creates a dummy file, not an actual image
img_path = temp_dir / "test_image.jpg"
img_path.write_bytes(b"dummy image data")
return img_path


@pytest.fixture
def capture_logs(caplog):
"""Fixture to help capture and assert on log messages."""
with caplog.at_level("DEBUG"):
yield caplog


def pytest_configure(config):
"""Configure pytest with custom settings."""
# Add custom markers documentation
config.addinivalue_line(
"markers", "unit: mark test as a unit test"
)
config.addinivalue_line(
"markers", "integration: mark test as an integration test"
)
config.addinivalue_line(
"markers", "slow: mark test as slow running"
)


def pytest_collection_modifyitems(config, items):
"""Modify test collection to add markers based on location."""
for item in items:
# Auto-mark tests based on their location
if "unit" in str(item.fspath):
item.add_marker(pytest.mark.unit)
elif "integration" in str(item.fspath):
item.add_marker(pytest.mark.integration)
Empty file added tests/integration/__init__.py
Empty file.
Loading