meta_ai_TeamTitans / tests /test_environment.py
NeuralWeave's picture
initial project structure
81287bd
Raw
History Blame Contribute Delete
3.54 kB
"""
tests/test_environment.py — Unit Tests for the RL Environment
==============================================================
Run: pytest tests/test_environment.py -v
Tests: reset(), step(), reward math, done conditions, relationship decay
"""
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "server"))
import pytest
from server.environment import EmailTriageEnv
@pytest.fixture
def env():
"""Fresh environment for each test."""
return EmailTriageEnv()
def test_reset_returns_observation(env):
obs = env.reset()
assert obs.email_id >= 0
assert obs.sender != ""
assert obs.time_budget_remaining == 480
def test_reset_populates_inbox(env):
env.reset()
state = env.state()
assert len(state.inbox) == 20 # Task 1 default: 20 emails
def test_reset_initializes_relationships(env):
env.reset()
state = env.state()
assert len(state.relationships) > 0
for rel in state.relationships.values():
assert rel.health == 75.0 # All start at 75
def test_step_respond_decreases_time(env):
env.reset()
state_before = env.state()
env.step(1) # RESPOND
state_after = env.state()
assert state_after.time_budget_remaining < state_before.time_budget_remaining
def test_step_ignore_preserves_time(env):
env.reset()
state_before = env.state()
env.step(0) # IGNORE
state_after = env.state()
assert state_after.time_budget_remaining == state_before.time_budget_remaining
def test_step_respond_increases_relationship_health(env):
env.reset()
state_before = env.state()
obs = env.state()
# Find sender of first email
first_email = state_before.inbox[0]
sender = first_email.sender
if first_email.sender_importance != "Spam":
health_before = state_before.relationships[sender].health
env.step(1) # RESPOND
state_after = env.state()
health_after = state_after.relationships[sender].health
assert health_after >= health_before
def test_step_ignore_vip_sets_angry(env):
env.reset()
state = env.state()
# Find a VIP email
vip_email = next((e for e in state.inbox if e.sender_importance == "VIP"), None)
if vip_email is None:
pytest.skip("No VIP email in this episode")
# Advance to VIP email
for i in range(state.inbox.index(vip_email)):
env.step(1) # Skip past earlier emails
# Ignore the VIP
env.step(0)
state_after = env.state()
assert state_after.relationships[vip_email.sender].is_angry == True
def test_done_when_inbox_empty(env):
env.reset()
state = env.state()
num_emails = len(state.inbox)
result = None
for _ in range(num_emails):
result = env.step(1)
assert result.done == True
def test_reward_positive_for_high_priority_respond(env):
env.reset()
state = env.state()
# Find high-priority email
high_priority = next((e for e in state.inbox if e.base_priority >= 7), None)
if high_priority is None:
pytest.skip("No high priority email")
for i in range(state.inbox.index(high_priority)):
env.step(1)
result = env.step(1) # Respond to high priority
assert result.reward > 0
def test_state_is_deep_copy(env):
env.reset()
state1 = env.state()
env.step(0)
state2 = env.state()
# They should differ — step 0 advanced the index
assert state1.current_email_index != state2.current_email_index