robomind-vla / tests_comprehensive.py
mitvho09's picture
RoboMind VLA: vision-language reward model for robot locomotion (built with Codex)
321ba64 verified
Raw
History Blame Contribute Delete
7 kB
"""
RoboMind VLA — Comprehensive Test Suite.
Tests:
- Unit tests for hybrid_judge module
- Unit tests for sound detection
- Integration test for end-to-end pipeline
- Regression tests for known predictions
Run:
python -m pytest tests_comprehensive.py -v
"""
import json
import sys
import os
sys.path.insert(0, os.path.dirname(__file__))
class TestHybridJudge:
"""Test the hybrid judge module."""
def test_vlm_to_reward_stable(self):
from robomind.hybrid import vlm_to_reward
parsed = {"stability": "stable", "gait_quality": 0.9, "predicted_reward": 0.95}
reward, confidence, details = vlm_to_reward(parsed)
assert 0.7 <= reward <= 1.0, f"Expected high reward for stable, got {reward}"
assert confidence > 0.5, f"Expected high confidence, got {confidence}"
def test_vlm_to_reward_falling(self):
from robomind.hybrid import vlm_to_reward
parsed = {"stability": "falling", "gait_quality": 0.0, "predicted_reward": 0.0, "anomaly": "fell through ground"}
reward, confidence, details = vlm_to_reward(parsed)
assert reward < 0.2, f"Expected low reward for falling, got {reward}"
def test_vlm_to_reward_text_values(self):
from robomind.hybrid import vlm_to_reward
parsed = {"stability": "stable", "gait_quality": "good", "predicted_reward": "high"}
reward, confidence, details = vlm_to_reward(parsed)
assert 0.5 <= reward <= 1.0, f"Expected reasonable reward, got {reward}"
def test_rule_based_expert(self):
from robomind.hybrid import rule_based_reward
reward, explanation = rule_based_reward(10000, 5000, 11000, False, 1000, "expert")
assert reward > 0.7, f"Expected high reward for expert, got {reward}"
def test_rule_based_simple(self):
from robomind.hybrid import rule_based_reward
reward, explanation = rule_based_reward(4000, 5000, 11000, False, 1000, "simple")
assert reward < 0.3, f"Expected low reward for simple, got {reward}"
def test_rule_based_fell(self):
from robomind.hybrid import rule_based_reward
reward, explanation = rule_based_reward(10000, 5000, 11000, True, 1000, "expert")
assert reward == 0.0, f"Expected zero reward for fall, got {reward}"
def test_blend_rewards(self):
from robomind.hybrid import blend_rewards
blended, rule_w = blend_rewards(0.9, 0.8, 0.5)
assert 0.5 < blended < 0.9, f"Expected blended between 0.5-0.9, got {blended}"
def test_hybrid_judge_expert(self):
from robomind.hybrid import hybrid_judge, hybrid_to_dict
parsed = {"stability": "stable", "gait_quality": 0.9, "predicted_reward": 0.95}
score = hybrid_judge(parsed, ep_return=10000, min_return=5000, max_return=11000, fell=False, tier="expert")
assert score.blended_reward > 0.7, f"Expected expert > 0.7, got {score.blended_reward}"
assert score.method == "hybrid"
def test_hybrid_judge_vlm_only(self):
from robomind.hybrid import hybrid_judge
parsed = {"stability": "stable", "gait_quality": 0.9, "predicted_reward": 0.95}
score = hybrid_judge(parsed)
assert score.method == "vlm_only"
def test_hybrid_to_dict(self):
from robomind.hybrid import hybrid_judge, hybrid_to_dict
parsed = {"stability": "stable", "gait_quality": 0.8, "predicted_reward": 0.9}
score = hybrid_judge(parsed)
d = hybrid_to_dict(score)
assert "predicted_reward" in d
assert "vlm_reward" in d
assert "rule_reward" in d
assert "method" in d
class TestSoundDetection:
"""Test the sound detection module."""
def test_audio_features_defaults(self):
from robomind.sound import AudioFeatures
f = AudioFeatures()
assert f.rms_energy == 0.0
assert f.peak_amplitude == 0.0
def test_sound_analysis_no_sound(self):
from robomind.sound import SoundAnalyzer, AudioFeatures
analyzer = SoundAnalyzer()
features = AudioFeatures(rms_energy=0.01, peak_amplitude=0.05, silence_ratio=0.9)
analysis = analyzer._analyze(features)
assert not analysis.has_fall
assert not analysis.has_impact
def test_sound_analysis_fall(self):
from robomind.sound import SoundAnalyzer, AudioFeatures
analyzer = SoundAnalyzer()
features = AudioFeatures(peak_amplitude=0.9, impact_severity=0.7, silence_ratio=0.5)
analysis = analyzer._analyze(features)
assert analysis.has_fall
assert analysis.fall_confidence > 0
def test_sound_analysis_gait(self):
from robomind.sound import SoundAnalyzer, AudioFeatures
analyzer = SoundAnalyzer()
features = AudioFeatures(gait_regularity=0.8, tempo=120.0)
analysis = analyzer._analyze(features)
assert analysis.has_rhythmic_gait
class TestJudge:
"""Test the VLM judge module."""
def test_parse_response_json(self):
from robomind.judge import RoboMindJudge
response = '{"stability": "stable", "predicted_reward": 0.9}'
parsed = RoboMindJudge._parse_response(response)
assert parsed["stability"] == "stable"
assert parsed["predicted_reward"] == 0.9
def test_parse_response_with_text(self):
from robomind.judge import RoboMindJudge
response = "Here is my analysis:\n```json\n{\"stability\": \"wobbling\", \"predicted_reward\": 0.5}\n```"
parsed = RoboMindJudge._parse_response(response)
assert "stability" in parsed
class TestIntegration:
"""Integration tests."""
def test_full_pipeline(self):
from robomind.hybrid import hybrid_judge, hybrid_to_dict
vlm_parsed = {
"stability": "stable",
"fall_risk": "low",
"gait_quality": 0.85,
"predicted_reward": 0.9,
"anomaly": None,
}
score = hybrid_judge(
vlm_parsed, ep_return=8000, min_return=4000, max_return=10000,
fell=False, num_steps=1000, tier="medium", env="walker2d",
)
result = hybrid_to_dict(score)
assert result["method"] == "hybrid"
assert 0.0 <= result["predicted_reward"] <= 1.0
assert 0.0 <= result["vlm_reward"] <= 1.0
assert 0.0 <= result["rule_reward"] <= 1.0
def test_tier_ordering(self):
from robomind.hybrid import hybrid_judge
rewards = {}
for tier, ep_ret in [("expert", 10000), ("medium", 7000), ("simple", 4500)]:
parsed = {"stability": "stable", "gait_quality": 0.8, "predicted_reward": 0.85}
score = hybrid_judge(parsed, ep_return=ep_ret, min_return=4000, max_return=11000, fell=False, tier=tier)
rewards[tier] = score.blended_reward
assert rewards["expert"] > rewards["medium"] > rewards["simple"], \
f"Expected expert > medium > simple, got {rewards}"
if __name__ == "__main__":
import pytest
pytest.main([__file__, "-v"])