"""Tests for fluency assessment rule and abandonment tracking.""" import pytest from agenteval.evaluation.rules.base import get_rule from agenteval.models import Case, RunSummary, Turn def test_run_summary_abandonment_fields(): """RunSummary should have abandonment tracking fields.""" summary = RunSummary( total_cases=10, passed_cases=7, failed_cases=2, abandoned_cases=1, ) assert summary.total_cases == 10 assert summary.abandoned_cases == 1 assert summary.abandonment_rate is None # Not calculated yet def test_run_summary_abandonment_rate_calculation(): """Abandonment rate should be calculable from summary fields.""" summary = RunSummary( total_cases=10, abandoned_cases=2, ) # Calculate abandonment rate if summary.total_cases > 0: rate = summary.abandoned_cases / summary.total_cases assert rate == 0.2 def test_fluency_rule_registered(): """Fluency rule should be registered in the rule registry.""" from agenteval.evaluation.rules import list_rule_types assert "fluency" in list_rule_types() def test_fluency_rule_config(): """Fluency rule should accept configuration parameters.""" rule = get_rule( "fluency", {"min_score": 8, "criteria": "评估对话是否自然流畅"}, ) assert rule.params["min_score"] == 8 assert rule.params["criteria"] == "评估对话是否自然流畅" def test_fluency_rule_empty_dialog(): """Fluency rule should fail on empty dialog.""" rule = get_rule("fluency", {"min_score": 7}) case = Case(id="c1", messages=["hello"]) import asyncio result = asyncio.run(rule.evaluate(case, [])) assert result.passed is False assert "无回复记录" in result.reason @pytest.mark.asyncio async def test_fluency_rule_no_model_config(): """Fluency rule should fail without model configuration.""" rule = get_rule("fluency", {"min_score": 7}) case = Case(id="c1", messages=["hello"]) dialog = [ Turn( id="t1", run_id="r1", case_id="c1", round_index=1, sent_message={"msgBody": "你好"}, reply={"msgBody": "您好,有什么可以帮助您的?"}, ) ] result = await rule.evaluate(case, dialog) assert result.passed is False assert "未绑定评估模型" in result.reason def test_fluency_rule_default_min_score(): """Fluency rule should have default min_score of 7.""" rule = get_rule("fluency", {}) assert rule.params.get("min_score", 7) == 7 def test_abandonment_rate_zero_total(): """Abandonment rate should handle zero total cases.""" summary = RunSummary(total_cases=0, abandoned_cases=0) # Should not raise division by zero if summary.total_cases > 0: rate = summary.abandoned_cases / summary.total_cases else: rate = None assert rate is None def test_abandonment_rate_all_abandoned(): """Abandonment rate should be 1.0 when all cases are abandoned.""" summary = RunSummary(total_cases=5, abandoned_cases=5) rate = summary.abandoned_cases / summary.total_cases assert rate == 1.0 def test_abandonment_rate_none_abandoned(): """Abandonment rate should be 0.0 when no cases are abandoned.""" summary = RunSummary(total_cases=5, abandoned_cases=0) rate = summary.abandoned_cases / summary.total_cases assert rate == 0.0