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
Binary file added .coverage.636f8bfcde6c.4202.XwIoUvwx
Binary file not shown.
64 changes: 58 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,59 @@
# IDE
.vscode/
outputs
checkpoints
__pycache__
*/__pycache__
*.pyc
gradio*
.idea/
*.swp
*.swo
*~

# Python
__pycache__/
*/__pycache__/
*.py[cod]
*$py.class
*.so
.Python
env/
venv/
ENV/
.venv/
virtualenv/

# Testing
.pytest_cache/
.coverage
htmlcov/
coverage.xml
*.cover
.hypothesis/
.tox/
nosetests.xml

# Build artifacts
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Project specific
outputs/
checkpoints/
gradio*
*.log
*.tmp

# Claude settings
.claude/*

# Package manager
poetry.lock
101 changes: 101 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
[tool.poetry]
name = "video-depth-anything"
version = "0.1.0"
description = "Video Depth Anything: Consistent Depth Estimation for Open-world Videos"
authors = ["Your Name <your.email@example.com>"]
readme = "README.md"
license = "MIT"

[tool.poetry.dependencies]
python = "^3.8"
numpy = "1.23.1"
torch = "2.1.1"
torchvision = "0.16.1"
opencv-python = "*"
matplotlib = "*"
pillow = "*"
imageio = "2.19.3"
imageio-ffmpeg = "0.4.7"
decord = {version = "*", optional = true}
xformers = "0.0.23"
einops = "0.4.1"
easydict = "*"
tqdm = "*"
OpenEXR = "3.3.1"

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

[tool.poetry.scripts]
test = "pytest:main"
tests = "pytest:main"

[tool.pytest.ini_options]
minversion = "8.0"
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = [
"-v",
"--strict-markers",
"--tb=short",
"--cov=video_depth_anything",
"--cov=metric_depth",
"--cov=benchmark",
"--cov=utils",
"--cov-report=term-missing",
"--cov-report=html:htmlcov",
"--cov-report=xml:coverage.xml",
"--cov-fail-under=0",
]
markers = [
"unit: Unit tests",
"integration: Integration tests",
"slow: Slow running tests",
]
filterwarnings = [
"error",
"ignore::UserWarning",
"ignore::DeprecationWarning",
]

[tool.coverage.run]
source = ["video_depth_anything", "metric_depth", "benchmark", "utils"]
omit = [
"*/tests/*",
"*/__pycache__/*",
"*/site-packages/*",
"*/distutils/*",
"*/.venv/*",
"*/venv/*",
"*/virtualenv/*",
]

[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if self.debug:",
"if __name__ == .__main__.:",
"raise AssertionError",
"raise NotImplementedError",
"if 0:",
"if False:",
"pass",
]
precision = 2
show_missing = true
skip_covered = false

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

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

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
9 changes: 9 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Test package for video-depth-anything."""

# Add the project root to the Python path
import sys
from pathlib import Path

project_root = Path(__file__).parent.parent
if str(project_root) not in sys.path:
sys.path.insert(0, str(project_root))
154 changes: 154 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
"""Shared pytest fixtures and configuration for all tests."""

import os
import shutil
import tempfile
from pathlib import Path
from typing import Generator

import pytest
import torch
import numpy as np
from PIL import Image


@pytest.fixture
def temp_dir() -> Generator[Path, None, None]:
"""Create a temporary directory that is cleaned up after the test."""
temp_path = Path(tempfile.mkdtemp())
yield temp_path
shutil.rmtree(temp_path)


@pytest.fixture
def sample_image_path(temp_dir: Path) -> Path:
"""Create a sample RGB image for testing."""
img_path = temp_dir / "test_image.png"
# Create a simple 100x100 RGB image
img_array = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
img = Image.fromarray(img_array)
img.save(img_path)
return img_path


@pytest.fixture
def sample_video_path(temp_dir: Path) -> Path:
"""Create a sample video file path for testing (mock)."""
# Note: This is just a path fixture for testing file handling
# Actual video creation would require imageio-ffmpeg
video_path = temp_dir / "test_video.mp4"
video_path.touch() # Create empty file for path testing
return video_path


@pytest.fixture
def sample_tensor() -> torch.Tensor:
"""Create a sample torch tensor for testing."""
return torch.randn(1, 3, 224, 224)


@pytest.fixture
def sample_depth_map() -> np.ndarray:
"""Create a sample depth map for testing."""
return np.random.rand(480, 640).astype(np.float32)


@pytest.fixture
def mock_model_config() -> dict:
"""Mock configuration for model testing."""
return {
"encoder": "dinov2",
"decoder": "dpt",
"input_size": [224, 224],
"output_size": [480, 640],
"pretrained": False,
"temporal": True,
"motion_module": {
"enabled": True,
"num_frames": 8
}
}


@pytest.fixture
def mock_dataset_config() -> dict:
"""Mock configuration for dataset testing."""
return {
"name": "test_dataset",
"root_dir": "/tmp/test_data",
"batch_size": 4,
"num_workers": 2,
"shuffle": True,
"transform": {
"resize": [224, 224],
"normalize": True
}
}


@pytest.fixture
def environment_setup(monkeypatch):
"""Set up test environment variables."""
monkeypatch.setenv("CUDA_VISIBLE_DEVICES", "0")
monkeypatch.setenv("PYTHONPATH", str(Path(__file__).parent.parent))


@pytest.fixture(autouse=True)
def torch_deterministic():
"""Make torch operations deterministic for testing."""
torch.manual_seed(42)
np.random.seed(42)
# Store original settings
old_deterministic = torch.backends.cudnn.deterministic
old_benchmark = torch.backends.cudnn.benchmark

# Set deterministic mode
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False

yield

# Restore original settings
torch.backends.cudnn.deterministic = old_deterministic
torch.backends.cudnn.benchmark = old_benchmark


@pytest.fixture
def gpu_available() -> bool:
"""Check if GPU is available for testing."""
return torch.cuda.is_available()


@pytest.fixture
def skip_if_no_gpu(gpu_available):
"""Skip test if GPU is not available."""
if not gpu_available:
pytest.skip("GPU not available")


class MockResponse:
"""Mock HTTP response for testing."""
def __init__(self, content: bytes, status_code: int = 200):
self.content = content
self.status_code = status_code

def raise_for_status(self):
if self.status_code != 200:
raise Exception(f"HTTP {self.status_code}")


@pytest.fixture
def mock_http_response():
"""Factory for creating mock HTTP responses."""
def _create_response(content: bytes = b"test", status_code: int = 200):
return MockResponse(content, status_code)
return _create_response


# Markers for different test types
def pytest_configure(config):
"""Configure pytest with custom markers."""
config.addinivalue_line("markers", "unit: Unit tests")
config.addinivalue_line("markers", "integration: Integration tests")
config.addinivalue_line("markers", "slow: Slow running tests")
config.addinivalue_line("markers", "gpu: Tests requiring GPU")
Empty file added tests/integration/__init__.py
Empty file.
Loading