NeuroSAM3 / test_app.py
copilot-swe-agent[bot]
Address code review: use single .to() call and improve test precision
833b39a
#!/usr/bin/env python3
"""
End-to-end test script for NeuroSAM 3 app
Tests app structure, imports, and function logic without requiring GPU/model
"""
import sys
import os
import ast
import importlib.util
print("=" * 70)
print("πŸ§ͺ NeuroSAM 3 App - End-to-End Test")
print("=" * 70)
# Test 1: Check if app.py exists and is readable
print("\n[1/8] Checking app.py file...")
# Use path relative to this script
script_dir = os.path.dirname(os.path.abspath(__file__))
app_path = os.path.join(script_dir, "app.py")
if not os.path.exists(app_path):
print(f"❌ ERROR: app.py not found at {app_path}!")
sys.exit(1)
print(f"βœ… app.py found at {app_path}")
# Test 2: Check Python syntax
print("\n[2/8] Checking Python syntax...")
try:
with open(app_path, 'r') as f:
code = f.read()
ast.parse(code)
print("βœ… Python syntax is valid")
except SyntaxError as e:
print(f"❌ SYNTAX ERROR: {e}")
sys.exit(1)
# Test 3: Check required functions exist
print("\n[3/8] Checking required functions...")
required_functions = [
'process_medical_image',
'process_with_status',
'process_sequence',
'process_slices_for_viewer',
'navigate_slice',
'extract_subject_id',
'group_images_by_subject',
'compare_with_ground_truth',
'process_with_ground_truth',
'load_demo_file'
]
# Optional functions (may have different names)
optional_functions = [
'detect_subjects' # May be defined inline or with different name
]
missing_functions = []
for func_name in required_functions:
if f"def {func_name}" not in code:
missing_functions.append(func_name)
if missing_functions:
print(f"❌ Missing functions: {', '.join(missing_functions)}")
sys.exit(1)
print(f"βœ… All {len(required_functions)} required functions found")
# Test 4: Check Gradio components
print("\n[4/8] Checking Gradio UI components...")
required_components = [
'gr.Blocks()',
'gr.File(',
'gr.Image(',
'gr.Textbox(',
'gr.Dropdown(',
'gr.Button(',
'gr.Slider(',
'gr.Gallery(',
'gr.Tabs(',
'gr.Tab('
]
missing_components = []
for comp in required_components:
if comp not in code:
missing_components.append(comp)
if missing_components:
print(f"⚠️ Missing components: {', '.join(missing_components)}")
else:
print(f"βœ… All Gradio components found")
# Test 5: Check tabs structure
print("\n[5/8] Checking UI tabs...")
tabs = [
'Single Image',
'Interactive Slice Viewer',
'Gallery View',
'Compare with Ground Truth'
]
found_tabs = []
for tab in tabs:
if f'gr.Tab("{tab}")' in code or f"gr.Tab('{tab}')" in code:
found_tabs.append(tab)
print(f"βœ… Found tabs: {', '.join(found_tabs)}")
if len(found_tabs) != len(tabs):
print(f"⚠️ Expected {len(tabs)} tabs, found {len(found_tabs)}")
# Test 6: Check event handlers
print("\n[6/8] Checking event handlers...")
required_handlers = [
'submit_btn.click',
'submit_batch_btn.click',
'submit_gallery_btn.click',
'submit_gt_btn.click',
'detect_subjects_btn.click',
'slice_slider.change',
'prev_btn.click',
'next_btn.click',
'load_demo_btn.click'
]
found_handlers = []
for handler in required_handlers:
if handler in code:
found_handlers.append(handler)
print(f"βœ… Found {len(found_handlers)}/{len(required_handlers)} event handlers")
if len(found_handlers) < len(required_handlers):
missing = [h for h in required_handlers if h not in found_handlers]
print(f"⚠️ Missing handlers: {', '.join(missing)}")
# Test 7: Check imports
print("\n[7/8] Checking imports...")
required_imports = [
'import gradio',
'import torch',
'import pydicom',
'import numpy',
'from PIL import Image',
'from transformers import',
'import matplotlib',
'import tempfile',
'import os'
]
missing_imports = []
for imp in required_imports:
if imp not in code:
missing_imports.append(imp)
if missing_imports:
print(f"⚠️ Missing imports: {', '.join(missing_imports)}")
else:
print("βœ… All required imports found")
# Test 8: Check for common errors
print("\n[8/8] Checking for common errors...")
errors_found = []
# Check for undefined variables in function calls
if 'processed_results_cache' not in code:
errors_found.append("processed_results_cache not defined")
# Check if demo.launch() exists
if 'demo.launch(' not in code:
errors_found.append("demo.launch() call not found")
# Check for HF_TOKEN handling
if 'HF_TOKEN' not in code:
errors_found.append("HF_TOKEN handling not found")
elif 'os.getenv("HF_TOKEN")' not in code:
errors_found.append("HF_TOKEN not retrieved from environment")
if errors_found:
print(f"❌ Errors found: {', '.join(errors_found)}")
else:
print("βœ… No common errors detected")
# Summary
print("\n" + "=" * 70)
print("πŸ“Š Test Summary")
print("=" * 70)
all_passed = (
len(missing_functions) == 0 and
len(errors_found) == 0
)
if all_passed:
print("βœ… All critical tests passed!")
print("\nπŸ’‘ Next steps:")
print(" 1. Set HF_TOKEN environment variable")
print(" 2. Test on Hugging Face Space")
print(" 3. Upload test DICOM/images to verify functionality")
sys.exit(0)
else:
print("❌ Some tests failed. Please review the errors above.")
sys.exit(1)