Skip to content

测试护栏与演进落点

测试护栏在当前项目里不是附属物,而是架构边界的可执行表达。哪些测试存在、测到哪一层、替换点是否可注入,直接决定系统边界是不是还站得住。

后端测试护栏

Use case 层

测试保护的边界
tests/use_cases/test_send_chat_message_use_case.pyChat 主链编排
tests/use_cases/test_generate_prescription_use_case.py处方生成主链
tests/use_cases/test_manage_prescription_use_case.py当前处方 / 替换处方
tests/use_cases/test_perform_safety_check_use_case.pysafety use case
tests/use_cases/test_submit_full_assessment_use_case.pyassessment use case
tests/use_cases/test_get_health_overview_use_case.pycompanion overview use case
tests/use_cases/test_use_case_package_exports.pyuse case package public surface

API adapter 层

测试保护的边界
tests/api/test_auth.pyauth API
tests/api/test_auth_dependency.pyauth dependency / 注入边界
tests/api/test_chat_disclaimer_gate.pychat safety / disclaimer gate
tests/api/test_prescription.pyprescription API
tests/api/test_sport.pysport API
tests/api/test_user.pyuser API
tests/api/test_main_cors_configuration.pyCORS / app factory 口径
tests/api/test_story_7_4_fixes.py主链回归样本

Core / runtime / public surface

测试保护的边界
tests/core/test_runtime_settings_usage.pyruntime settings 读取边界
tests/core/test_database_url.pyDB URL 规范化
tests/core/test_profile_validation_rules.pyprofile 校验可信源
tests/core/test_safety_public_surface.pysafety public surface
tests/core/test_rag_package_exports.pyRAG package export guard
tests/core/test_prescription_payload.pycanonical payload helper
tests/core/test_dialogue_payload.pydialogue payload helper

Flutter 测试护栏

API / 注入 / contract

测试保护的边界
test/api/replacement_point_contract_test.dartAPI client 替换点 contract
test/bloc/chat/chat_bloc_injection_test.dartChatBloc 注入 ChatApiClient
test/api/auth_api_client_test.dartauth client
test/api/prescription_api_client_test.dartprescription client

Screen / widget / integration

测试保护的边界
test/screens/chat/chat_screen_test.dartChat screen 主行为
test/screens/home/home_layout_test.dart首页布局骨架
test/screens/home/profile_page_test.dartProfile 页面桥接
test/screens/onboarding/onboarding_flow_screen_test.dart建档流程
test/screens/exercise/exercise_execution_screen_test.dart运动执行页
test/integration/exercise_feedback_flow_test.dart运动反馈链路
test/integration/ui_consistency_test.dartUI 一致性

为什么这些测试等于“架构护栏”

1. 它们锚定了主链落点

  • backend 的 chat / prescription / assessment / companion 主链都已在 use case 层有测试。
  • 这使得新增逻辑如果绕开 use case、直接回流到 router,更容易被看见和质疑。

2. 它们锚定了替换点是否仍可注入

  • Flutter 已明确测试 Diohttp.Clientsecure storagemultipart factory 的可替换性。
  • 这能防止前端 client 慢慢退化回写死依赖、难测对象。

3. 它们锚定了运行时装配口径

  • backend 有 runtime settingsauth dependencyCORS config 等测试。
  • 这能保护 main -> bootstrap -> runtime 这条装配骨架不会悄悄漂移。

新增功能的推荐落点

新增 backend 主链功能

  1. 先定义 command/result。
  2. app/use_cases/<feature>/ 实现业务编排。
  3. API route 只做 adapter。
  4. 依赖 runtime/service/repository,不直接在 route 内新建复杂对象。
  5. 至少补:
    • use case test
    • API adapter test

新增 Flutter 主链功能

  1. 判断是否需要新 BLoC。
  2. 需要跨页面、API、存储或业务流程的状态,进入 lib/bloc/<feature>/
  3. API 调用进入 lib/api/*ApiClient,保持可注入。
  4. screen/widget 负责状态渲染、事件派发和轻导航。
  5. 至少补:
    • bloc test 或 injection test
    • screen / widget test

如果功能只是代码保留或隐藏入口页的维护,例如 HealthOverviewScreenWeeklyReportScreen,测试存在只能证明实现仍可维护;是否重新纳入主流程,需要先回到产品入口和路由文档确认可达性。

当前不应误判的点

  • 测试多,不等于架构已经完美;它只说明当前关键边界已有护栏。
  • weekly_report 相关测试存在,不等于 weekly_report 已是当前主线已上线能力。
  • RAG 测试很多,但 RAG 仍然是专项边界,不应在主线架构里被展开成普通模块开发指南。

测试缺口判断

变更类型没有测试时的风险
backend route 变更API contract、鉴权、状态码和错误响应容易漂移
use case 变更主链编排可能被 router 或 service 隐式接管
runtime / config 变更本地与生产依赖解析可能出现不一致
Flutter API client 变更token、base URL、错误归一化和替换点容易失效
Flutter BLoC 变更loading / loaded / error 状态可能与页面渲染脱节
页面导航变更清栈、返回、tab switch、隐藏入口页口径容易被误改
RAG / LLM 变更召回、生成、安全边界和 provider fallback 难以审计

阅读建议

如果目的是判断“当前系统能不能安全接着改”,优先看:

  1. backend use_casesapi 测试
  2. Flutter 的替换点 contract 和关键页面测试
  3. runtime / public surface guard

如果这些测试的边界仍然清晰,说明系统至少在主链和替换点上仍然有基本护栏;如果这些测试开始失真,通常比单个页面样式问题更值得优先处理。

来源锚点

  • apps/backend_service/tests/use_cases/
  • apps/backend_service/tests/api/
  • apps/backend_service/tests/core/
  • apps/flutter_app/test/api/
  • apps/flutter_app/test/bloc/
  • apps/flutter_app/test/screens/
  • apps/flutter_app/test/integration/