Skip to content

Latest commit

 

History

History
111 lines (80 loc) · 3.21 KB

File metadata and controls

111 lines (80 loc) · 3.21 KB

✅ 完成:自动测试发现功能

目标

确保所有使用 @evaluation_test 装饰的函数都能被 pytest 自动发现,无论函数名是否符合 pytest 命名规范。

实现方案

核心机制:自动注册

当函数名不以 test_ 开头时,decorator 会:

  1. 自动在调用者的全局命名空间中注册一个以 test_ 开头的别名
  2. Pytest 扫描模块时会发现这个别名
  3. 用户无需修改任何代码或命名

代码修改

1. eval_protocol/pytest/evaluation_test.py

  • ✅ 移除了警告功能
  • ✅ 添加了自动注册逻辑(使用 sys._getframe 访问调用者的全局命名空间)

2. eval_protocol/pytest/parameterize.py

  • ✅ 确保 wrapper 的 __name__ 属性以 test_ 开头

3. eval_protocol/pytest/dual_mode_wrapper.py

  • ✅ 确保 dual_mode_wrapper 的 __name__ 属性以 test_ 开头

使用示例

from eval_protocol.pytest import evaluation_test
from eval_protocol.models import EvaluationRow, EvaluateResult

# ✅ 不需要以 test_ 开头 - 会自动注册为 test_my_evaluation
@evaluation_test(
    input_rows=[[EvaluationRow(messages=[{"role": "user", "content": "Hello"}])]]
)
async def my_evaluation(row: EvaluationRow) -> EvaluationRow:
    row.evaluation_result = EvaluateResult(score=1.0)
    return row

# ✅ 已经符合命名规范 - 正常工作
@evaluation_test(
    input_rows=[[EvaluationRow(messages=[{"role": "user", "content": "Hello"}])]]
)
async def test_my_evaluation(row: EvaluationRow) -> EvaluationRow:
    row.evaluation_result = EvaluateResult(score=1.0)
    return row

验证结果

$ pytest --collect-only tests/test_auto_discovery_simple.py -v
collected 2 items

<Module test_auto_discovery_simple.py>
  <Coroutine test_my_custom_eval[rows(len=1)]>  # 自动注册!
  <Coroutine test_proper_eval[rows(len=1)]>

$ pytest tests/test_auto_discovery_simple.py -v
============================== 2 passed in 0.15s ==============================

特点

✅ 优点

  1. 零配置:无需任何额外配置
  2. 无需警告:静默自动处理,不打扰用户
  3. 完全兼容:不影响已有代码
  4. 简单直接:用户只需使用 @evaluation_test,其他都自动处理
  5. 可靠:经过测试验证

🎯 工作原理

  • Pytest 通过扫描模块的全局命名空间来发现测试
  • 我们在装饰时自动在命名空间中注册正确命名的别名
  • 用户原始函数名保持不变,可以继续使用

测试覆盖

  • tests/test_auto_discovery_simple.py - 验证自动发现功能
    • 测试不以 test_ 开头的函数能被发现
    • 测试以 test_ 开头的函数正常工作
    • 所有测试通过

文档

  • development/auto_test_discovery.md - 详细技术文档
  • development/FINAL_SUMMARY.md - 本文档

总结

现在,用户只需要:

@evaluation_test(...)
async def any_function_name(row: EvaluationRow) -> EvaluationRow:
    # 无论函数名是什么,都能被 pytest 发现!
    ...

就这么简单! 🎉

不需要:

  • ❌ 记住命名规范
  • ❌ 收到警告信息
  • ❌ 手动配置 pytest
  • ❌ 修改现有代码

只要使用 @evaluation_test,就能保证测试被发现!✨