File size: 3,611 Bytes
e1c010e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | """
Tests for the Visualization Module — ActionVisualizer.
"""
import numpy as np
import pytest
from src.visualization.visualizer import ActionVisualizer
class TestActionVisualizer:
"""Tests for ActionVisualizer methods."""
@pytest.fixture
def visualizer(self) -> ActionVisualizer:
return ActionVisualizer()
@pytest.fixture
def test_image(self) -> np.ndarray:
"""A 480x640 synthetic test image."""
return np.zeros((480, 640, 3), dtype=np.uint8)
@pytest.fixture
def sample_detections(self) -> list[dict]:
return [
{"label": "bottle", "confidence": 0.92, "bbox": [100, 150, 200, 350]},
{"label": "box", "confidence": 0.85, "bbox": [400, 300, 550, 500]},
]
@pytest.fixture
def sample_action_plan(self) -> dict:
return {
"action": "move",
"steps": [
"Step 1: Locate 'bottle'",
"Step 2: Locate 'box'",
"Step 3: Move 'bottle' → 'box'",
"Step 4: Verify action completion",
],
"source_bbox": [100, 150, 200, 350],
"dest_bbox": [400, 300, 550, 500],
"status": "success",
}
def test_draw_detections_returns_image(
self, visualizer, test_image, sample_detections
):
"""draw_detections should return an image of the same shape."""
result = visualizer.draw_detections(test_image, sample_detections)
assert isinstance(result, np.ndarray)
assert result.shape == test_image.shape
def test_draw_detections_modifies_image(
self, visualizer, test_image, sample_detections
):
"""draw_detections should modify the image (not return a blank copy)."""
result = visualizer.draw_detections(test_image, sample_detections)
# The annotated image should differ from the original
assert not np.array_equal(result, test_image)
def test_draw_detections_empty_list(self, visualizer, test_image):
"""draw_detections with empty list should still return an image."""
result = visualizer.draw_detections(test_image, [])
assert isinstance(result, np.ndarray)
assert result.shape == test_image.shape
def test_visualize_returns_image(
self, visualizer, test_image, sample_action_plan
):
"""visualize should return an image of the same shape."""
result = visualizer.visualize(test_image, sample_action_plan)
assert isinstance(result, np.ndarray)
assert result.shape == test_image.shape
def test_visualize_modifies_image(
self, visualizer, test_image, sample_action_plan
):
"""visualize should modify the image."""
result = visualizer.visualize(test_image, sample_action_plan)
assert not np.array_equal(result, test_image)
def test_visualize_with_no_bboxes(self, visualizer, test_image):
"""visualize should handle missing bounding boxes gracefully."""
plan = {
"action": "inspect",
"steps": ["Step 1: Inspect object"],
"source_bbox": None,
"dest_bbox": None,
"status": "failed",
}
result = visualizer.visualize(test_image, plan)
assert isinstance(result, np.ndarray)
assert result.shape == test_image.shape
def test_draw_detections_invalid_image(self, visualizer):
"""draw_detections with None should return a fallback image."""
result = visualizer.draw_detections(None, [])
assert isinstance(result, np.ndarray)
|