"""Tests for go/no-go acceptance verdict.""" import pytest from agenteval.evaluation.go_no_go import ( AcceptanceCriteria, CriterionResult, GoNoGoVerdict, evaluate_go_no_go, ) def test_go_verdict_all_pass(): """All criteria met -> go.""" summary = { "judged_pass_rate": 0.96, "pass_rate": 0.95, "avg_latency_ms": 2000, } criteria = AcceptanceCriteria( judged_pass_rate_min=0.95, pass_rate_min=0.90, avg_latency_max_ms=5000, ) verdict = evaluate_go_no_go(summary, criteria) assert verdict.decision == "go" assert "达标" in verdict.summary assert all(r.passed for r in verdict.criteria_results) def test_no_go_verdict_core_failed(): """Core metric (pass rate) failed -> no_go.""" summary = { "judged_pass_rate": 0.80, "pass_rate": 0.75, } criteria = AcceptanceCriteria( judged_pass_rate_min=0.95, pass_rate_min=0.90, ) verdict = evaluate_go_no_go(summary, criteria) assert verdict.decision == "no_go" assert "不建议上线" in verdict.summary assert any(not r.passed for r in verdict.criteria_results) def test_conditional_verdict_non_core_risk(): """Core passed but non-core (latency) failed -> conditional.""" summary = { "judged_pass_rate": 0.96, "pass_rate": 0.95, "avg_latency_ms": 8000, } criteria = AcceptanceCriteria( judged_pass_rate_min=0.95, pass_rate_min=0.90, avg_latency_max_ms=5000, ) verdict = evaluate_go_no_go(summary, criteria) assert verdict.decision == "conditional" assert "风险" in verdict.summary def test_default_criteria(): """Default criteria should be applied when None.""" summary = { "judged_pass_rate": 0.96, "pass_rate": 0.95, } verdict = evaluate_go_no_go(summary, None) assert verdict.decision == "go" assert len(verdict.criteria_results) >= 1 def test_empty_summary(): """Empty summary -> conditional with no results.""" verdict = evaluate_go_no_go({}, None) assert verdict.decision == "conditional" assert "无可用指标" in verdict.summary assert len(verdict.criteria_results) == 0 def test_criterion_result_model(): """CriterionResult model should work correctly.""" result = CriterionResult( criterion="pass_rate", threshold=0.95, actual=0.96, passed=True, detail="通过率 96% >= 95%", ) assert result.criterion == "pass_rate" assert result.passed is True def test_verdict_model(): """GoNoGoVerdict model should work correctly.""" verdict = GoNoGoVerdict( decision="go", summary="测试通过", criteria_results=[], ) assert verdict.decision == "go" assert verdict.generated_at is not None def test_latency_only_when_configured(): """Latency should only be checked when avg_latency_max_ms is set.""" summary = { "judged_pass_rate": 0.96, "avg_latency_ms": 10000, # High latency } # Without latency threshold criteria_no_latency = AcceptanceCriteria(judged_pass_rate_min=0.95) verdict1 = evaluate_go_no_go(summary, criteria_no_latency) assert verdict1.decision == "go" assert all(r.criterion != "avg_latency_ms" for r in verdict1.criteria_results) # With latency threshold criteria_with_latency = AcceptanceCriteria( judged_pass_rate_min=0.95, avg_latency_max_ms=5000, ) verdict2 = evaluate_go_no_go(summary, criteria_with_latency) assert verdict2.decision == "conditional" assert any(r.criterion == "avg_latency_ms" for r in verdict2.criteria_results) def test_judged_pass_rate_fallback_to_pass_rate(): """If judged_pass_rate is missing, fall back to pass_rate.""" summary = {"pass_rate": 0.96} criteria = AcceptanceCriteria(judged_pass_rate_min=0.95) verdict = evaluate_go_no_go(summary, criteria) assert verdict.decision == "go" # Should have one result using pass_rate as judged_pass_rate assert len(verdict.criteria_results) == 1 assert verdict.criteria_results[0].criterion == "judged_pass_rate" assert verdict.criteria_results[0].actual == 0.96