DIVYANSHI SINGH commited on
Commit ·
d9d424f
1
Parent(s): a7bdbfb
chore: Organized all test scripts into a dedicated tests/ package
Browse files- tests/__init__.py +0 -0
- tests/test_config.py +18 -0
- tests/test_detector.py +47 -0
- tests/test_gps.py +58 -0
- tests/test_utils.py +62 -0
tests/__init__.py
ADDED
|
File without changes
|
tests/test_config.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
|
| 3 |
+
def test_imports():
|
| 4 |
+
try:
|
| 5 |
+
import ultralytics
|
| 6 |
+
import cv2
|
| 7 |
+
import PIL
|
| 8 |
+
import folium
|
| 9 |
+
print(f"Ultralytics installed successfully: {ultralytics.__version__}")
|
| 10 |
+
assert ultralytics.__version__ == '8.2.18', "YOLO Version mismatch"
|
| 11 |
+
print("Initialization successful.")
|
| 12 |
+
except Exception as e:
|
| 13 |
+
print(f"Error during initialization: {e}")
|
| 14 |
+
sys.exit(1)
|
| 15 |
+
|
| 16 |
+
if __name__ == "__main__":
|
| 17 |
+
test_imports()
|
| 18 |
+
print("ALL TESTS PASSED")
|
tests/test_detector.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
| 4 |
+
|
| 5 |
+
import urllib.request
|
| 6 |
+
import numpy as np
|
| 7 |
+
import cv2
|
| 8 |
+
from detector import PotholeDetector
|
| 9 |
+
|
| 10 |
+
def test_singleton():
|
| 11 |
+
"""Assert singleton prevents memory bloat by persisting strict memory addresses"""
|
| 12 |
+
det1 = PotholeDetector.get_instance("yolov8n.pt")
|
| 13 |
+
det2 = PotholeDetector.get_instance("yolov8n.pt")
|
| 14 |
+
assert det1 is det2, "Singleton instantiation routing failed structurally."
|
| 15 |
+
print("test_singleton passed.")
|
| 16 |
+
|
| 17 |
+
def test_inference_shape_and_bgr():
|
| 18 |
+
"""Assert dictionary structures natively mapping BGR and asserting BGR performs distinct from RGB natively."""
|
| 19 |
+
det = PotholeDetector.get_instance("yolov8n.pt")
|
| 20 |
+
|
| 21 |
+
url = "https://ultralytics.com/images/zidane.jpg"
|
| 22 |
+
req = urllib.request.urlopen(url)
|
| 23 |
+
arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
|
| 24 |
+
img_bgr = cv2.imdecode(arr, -1) # BGR natively read
|
| 25 |
+
|
| 26 |
+
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
|
| 27 |
+
|
| 28 |
+
# Process dynamically natively evaluating constraints natively
|
| 29 |
+
results_bgr = det.predict(img_bgr, conf_thresh=0.25)
|
| 30 |
+
results_rgb = det.predict(img_rgb, conf_thresh=0.25)
|
| 31 |
+
|
| 32 |
+
assert isinstance(results_bgr, list), "Output casting payload failed structurally natively."
|
| 33 |
+
if len(results_bgr) > 0:
|
| 34 |
+
keys = list(results_bgr[0].keys())
|
| 35 |
+
assert 'xyxy' in keys and 'confidence' in keys and 'class_id' in keys, "Dictionary boundary keys mismatch."
|
| 36 |
+
|
| 37 |
+
conf_bgr = results_bgr[0]['confidence'] if results_bgr else 0.0
|
| 38 |
+
conf_rgb = results_rgb[0]['confidence'] if results_rgb else 0.0
|
| 39 |
+
|
| 40 |
+
# Assuming BGR provides exact precision vs RGB variant physically evaluating bounds natively
|
| 41 |
+
assert conf_bgr != conf_rgb, "Color space translation did not structurally impact physical YOLO tensor bindings (BGR vs RGB)."
|
| 42 |
+
print("test_inference_shape_and_bgr passed.")
|
| 43 |
+
|
| 44 |
+
if __name__ == "__main__":
|
| 45 |
+
test_singleton()
|
| 46 |
+
test_inference_shape_and_bgr()
|
| 47 |
+
print("ALL DETECTOR TESTS PASSED")
|
tests/test_gps.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import csv
|
| 3 |
+
import sys
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
| 6 |
+
from gps import dms_to_decimal, extract_gps_simple, find_nearest_gps, load_gps_log
|
| 7 |
+
|
| 8 |
+
def test_dms_to_decimal():
|
| 9 |
+
"""Validates mathematical tuple translations natively scaling numeric ranges."""
|
| 10 |
+
# Standard DMS tuple format mapping
|
| 11 |
+
tup = ((34, 1), (3, 1), (8, 1))
|
| 12 |
+
val_n = dms_to_decimal(tup, 'N')
|
| 13 |
+
assert abs(val_n - 34.052222) < 0.0001, "Positive DMS conversion calculation failed natively."
|
| 14 |
+
|
| 15 |
+
val_w = dms_to_decimal(tup, 'W')
|
| 16 |
+
assert val_w < 0, "Negative directional scaling failed natively for longitude conversion."
|
| 17 |
+
|
| 18 |
+
# Flat number failure mode test bridging mapping
|
| 19 |
+
val_flat = dms_to_decimal(34.0522, 'N')
|
| 20 |
+
assert val_flat == 34.0522, "Non-standard flat EXIF mapping conversion calculation failed natively."
|
| 21 |
+
print("test_dms_to_decimal passed.")
|
| 22 |
+
|
| 23 |
+
def test_load_gps_log():
|
| 24 |
+
"""Verify loading constraints targeting dynamic IO boundaries via mock structural datasets."""
|
| 25 |
+
export_path = Path("test_gps_log.csv")
|
| 26 |
+
with export_path.open('w', newline='', encoding='utf-8') as f:
|
| 27 |
+
writer = csv.DictWriter(f, fieldnames=['timestamp', 'latitude', 'longitude'])
|
| 28 |
+
writer.writeheader()
|
| 29 |
+
writer.writerow({'timestamp': '2026-04-05T12:00:00', 'latitude': '34.0', 'longitude': '-118.0'})
|
| 30 |
+
writer.writerow({'timestamp': '2026-04-05T12:05:00', 'latitude': '34.1', 'longitude': '-118.1'})
|
| 31 |
+
|
| 32 |
+
data = load_gps_log(export_path)
|
| 33 |
+
assert len(data) == 2, "Array length generation bounding issue."
|
| 34 |
+
assert data[0]['latitude'] == 34.0, "Parsing type casting boundary issue resolving floats physically."
|
| 35 |
+
|
| 36 |
+
export_path.unlink()
|
| 37 |
+
print("test_load_gps_log passed.")
|
| 38 |
+
|
| 39 |
+
def test_find_nearest_gps():
|
| 40 |
+
"""Assert minimum bridging bounding gap searches properly evaluate chronology distances natively."""
|
| 41 |
+
mock_log = [
|
| 42 |
+
{'timestamp': '2026-04-05T12:00:00', 'latitude': 34.0, 'longitude': -118.0},
|
| 43 |
+
{'timestamp': '2026-04-05T12:05:00', 'latitude': 34.1, 'longitude': -118.1},
|
| 44 |
+
{'timestamp': '2026-04-05T12:10:00', 'latitude': 34.2, 'longitude': -118.2}
|
| 45 |
+
]
|
| 46 |
+
|
| 47 |
+
# Target precisely in between index 0 and 1, closer to 1
|
| 48 |
+
target_ts = '2026-04-05T12:02:35'
|
| 49 |
+
nearest = find_nearest_gps(target_ts, mock_log)
|
| 50 |
+
|
| 51 |
+
assert nearest['latitude'] == 34.1, "Closest relative bounding gap calculation routing execution structurally failed natively."
|
| 52 |
+
print("test_find_nearest_gps passed.")
|
| 53 |
+
|
| 54 |
+
if __name__ == "__main__":
|
| 55 |
+
test_dms_to_decimal()
|
| 56 |
+
test_load_gps_log()
|
| 57 |
+
test_find_nearest_gps()
|
| 58 |
+
print("ALL GPS TESTS PASSED")
|
tests/test_utils.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import numpy as np
|
| 2 |
+
import base64
|
| 3 |
+
import sys
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
| 6 |
+
from utils import draw_boxes, image_to_base64, export_csv
|
| 7 |
+
|
| 8 |
+
def test_draw_boxes():
|
| 9 |
+
"""Test standard bounding box drawing alters the matrix"""
|
| 10 |
+
blank_img = np.zeros((100, 100, 3), dtype=np.uint8)
|
| 11 |
+
|
| 12 |
+
detections = [
|
| 13 |
+
{'xyxy': [10, 10, 50, 50], 'confidence': 0.95, 'class_id': 0}
|
| 14 |
+
]
|
| 15 |
+
|
| 16 |
+
annotated = draw_boxes(blank_img, detections)
|
| 17 |
+
|
| 18 |
+
assert not np.array_equal(blank_img, annotated), "Annotated image matches blank image; drawing failed."
|
| 19 |
+
print("test_draw_boxes passed.")
|
| 20 |
+
|
| 21 |
+
def test_image_to_base64():
|
| 22 |
+
"""Test image matrix converts robustly to base64 encoding sequences"""
|
| 23 |
+
blank_img = np.zeros((50, 50, 3), dtype=np.uint8)
|
| 24 |
+
b64_str = image_to_base64(blank_img)
|
| 25 |
+
|
| 26 |
+
assert isinstance(b64_str, str) and len(b64_str) > 0, "Base64 encoding failed; empty or wrong type returned."
|
| 27 |
+
|
| 28 |
+
decoded_bytes = base64.b64decode(b64_str)
|
| 29 |
+
assert len(decoded_bytes) > 0, "Decoded bytes are empty; padding issue potentially."
|
| 30 |
+
print("test_image_to_base64 passed.")
|
| 31 |
+
|
| 32 |
+
def test_export_csv():
|
| 33 |
+
"""Test rigorous external path creation logic and file integrity checking"""
|
| 34 |
+
detections = [
|
| 35 |
+
{'filename': 'test1.jpg', 'confidence': 0.9, 'latitude': 34.0, 'longitude': -118.0},
|
| 36 |
+
{'filename': 'test2.jpg', 'confidence': 0.8, 'latitude': 34.1, 'longitude': -118.1}
|
| 37 |
+
]
|
| 38 |
+
|
| 39 |
+
import tempfile
|
| 40 |
+
|
| 41 |
+
# Store directly in a Path container natively to meet restrictions
|
| 42 |
+
export_path = Path("test_output.csv")
|
| 43 |
+
export_csv(detections, export_path)
|
| 44 |
+
|
| 45 |
+
assert export_path.exists(), "CSV file was not successfully created."
|
| 46 |
+
|
| 47 |
+
with export_path.open('r', encoding='utf-8') as f:
|
| 48 |
+
content = f.read()
|
| 49 |
+
|
| 50 |
+
# Test accurate schema and value integrity locally
|
| 51 |
+
assert "filename" in content and "confidence" in content, "CSV headers missing from body."
|
| 52 |
+
assert "test1.jpg" in content and "0.9" in content, "CSV body row is missing expected data slice."
|
| 53 |
+
|
| 54 |
+
# Flush explicit testing payload back
|
| 55 |
+
export_path.unlink()
|
| 56 |
+
print("test_export_csv passed.")
|
| 57 |
+
|
| 58 |
+
if __name__ == "__main__":
|
| 59 |
+
test_draw_boxes()
|
| 60 |
+
test_image_to_base64()
|
| 61 |
+
test_export_csv()
|
| 62 |
+
print("ALL UTILS TESTS PASSED")
|