Files
skill-template/tests/samples/test_service_contract.py.sample
2026-05-03 17:52:52 +08:00

47 lines
2.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
# 本文件为样例:复制到 ``tests/test_service_contract.py``(或业务仓 tests 根)后按实际 service 改名运行。
# 默认 **不会** 被 ``python tests/run_tests.py`` 收集(扩展名为 .sample
"""
Service 层契约测试范式(示意)。
复制为真实技能后:
1. 将 ``from service.your_service import run`` 替换为实际模块与入口函数。
2. 用 ``FakeAdapter`` / 内存 stub 替代真实 ERP/TMS/WMS 等外呼。
3. 需要真实外网或真实 RPA 时,勿在本文件直接写死凭证;改用 ``tests/integration/*.sample`` + 环境开关。
"""
from __future__ import annotations
import unittest
from adapter_test_utils import FakeAdapter
# from service.your_service import run # noqa: ERA001 — 复制后取消注释并实现
class TestServiceContractSample(unittest.TestCase):
"""三类常见契约:成功路径、结构化错误、上游超时转可重试错误。"""
def test_success_path_returns_success_true(self) -> None:
# 示意run(payload, adapter=FakeAdapter("success")) -> {"success": True, ...}
ad = FakeAdapter("success")
out = ad.call({"op": "ping"})
self.assertTrue(out.get("success"))
def test_missing_required_field_returns_structured_error_not_bare_exception(self) -> None:
# 示意:业务层应对必填字段做校验,返回 {"success": False, "error": {"code": "...", "message": "..."}}
err = {"success": False, "error": {"code": "VALIDATION", "message": "missing shipment_id"}}
self.assertFalse(err["success"])
self.assertIn("code", err["error"])
def test_adapter_timeout_maps_to_retriable_error(self) -> None:
# 示意:捕获 TimeoutError 后映射为业务可重试错误码,而不是让裸异常穿透 CLI
ad = FakeAdapter("timeout")
with self.assertRaises(TimeoutError):
ad.call({})
# 真实实现中except TimeoutError: return {"success": False, "error": {"code": "UPSTREAM_TIMEOUT", "retriable": True}}
if __name__ == "__main__":
unittest.main()