
A2UI v0.9.1 协议 Schema 一致性测试实战指南JSON Schema 校验框架与用例编写【免费下载链接】a2ui项目地址: https://gitcode.com/GitHub_Trending/a2/a2uiA2UIAgent to UI通过 JSON Schema 定义了 Agent 与渲染客户端之间双向消息的协议边界。specification/v0_9_1/test/目录下的测试框架基于Python 3 ajv-cliDraft 2020-12提供了一套完整的协议一致性校验方案既能对服务端到客户端的server_to_client消息做严格的正反例验证也能对客户端到服务端的client_to_server事件做约束校验并通过 JSONL 流式样例检验整条对话链路的合法性。本文将以该目录下的 README 为骨架结合run_tests.py的运行机制、cases/下各类真实测试套件与json/目录中的 Schema 定义系统性讲解 A2UI v0.9.1 协议校验的目录结构、执行原理、用例编写方法与常见校验模式。一、测试目录结构与定位在进入具体命令之前先看清specification/v0_9_1/test/目录在仓库中的完整构成这是理解整个校验体系的前提specification/v0_9_1/test/ ├── README.md # 测试说明文档本文的骨架 ├── run_tests.py # Python 测试运行器核心驱动 ├── package.json # Yarn 依赖声明ajv-cli / ajv-formats └── cases/ # 测试套件与流式样例 ├── button_checks.json # Button 组件 checks 校验 ├── checkable_components.json # 可检查组件TextField/Slider/ChoicePicker 等 ├── client_messages.json # 客户端到服务端消息校验 ├── contact_form_example.jsonl # 端到端 JSONL 流式样例 ├── contact_form_example_test.json # 联系表单逐条消息用例 ├── function_catalog_validation.json # 函数目录调用校验 ├── tabs_checks.json # Tabs 组件结构校验 ├── text_variants.json # Text 组件 variant 校验 └── theme_validation.json # createSurface 主题校验与之配套的还有 specification/v0_9_1/json/ 下的 Schema 定义server_to_client.json、client_to_server.json、common_types.json等以及 specification/v0_9_1/catalogs/basic/catalog.json 组件目录。测试运行器会动态读取这些文件完成校验。二、环境准备与依赖安装README 明确了运行测试的两项前置条件Python 3用于执行run_tests.py测试运行器Yarn测试通过yarn调用ajv-cli完成 JSON Schema 校验。为了让测试执行更快可在测试目录下预先安装依赖cd specification/v0_9_1/test yarn installpackage.json 中声明了两个关键依赖ajv-cli^5.0.0与ajv-formats^3.0.1。ajv-cli 提供命令行校验能力而ajv-formats提供date-time、uri、email等标准格式校验器——这两者缺一不可稍后会看到它们在底层调用链中的具体作用。三、运行测试一次完整执行发生了什么从仓库根目录或测试目录均可直接运行python3 specification/v0_9_1/test/run_tests.py依据 README 的描述与 run_tests.py 的实际实现脚本执行流程如下加载 Schema从specification/v0_9_1/json加载全部 Schema 文件构建 catalog 别名setup_catalog_alias()读取 catalogs/basic/catalog.json将其$id重写为泛化的catalog.json通过正则^(https://a2ui\.org/specification/v0_\d/)匹配版本前缀并替换为catalog.json写入临时文件。这样server_to_client.json中引用catalog.json#/$defs/anyComponent时才能解析到同一份目录内容执行测试套件通过glob收集cases/*.json逐个套件运行run_suite()并额外对cases/contact_form_example.jsonl执行validate_jsonl_example()输出统计汇总打印Total Passed与Total Failed只要存在失败用例脚本以退出码 1 结束sys.exit(1)方便接入 CI。其中每一条用例的实际校验由validate_ajv()完成其底层拼装的 ajv 命令值得拆解yarn run ajv validate \ -s schema_path \ --specdraft2020 \ --strictfalse \ -c ajv-formats \ -d data_path \ -r 其余所有 schema 引用--specdraft2020指定 JSON Schema 方言为 Draft 2020-12与 server_to_client.json 头部声明的$schema一致--strictfalse关闭严格模式避免未声明关键字触发告警保证跨实现的宽松兼容-c ajv-formats启用格式校验插件使format: date-time、format: uri等约束真正生效-r把其他 Schema 作为引用一并加载实现跨文件$ref解析如common_types.json、catalog.json。每条用例的数据先被写入临时文件temp_data.json校验完成后在finally块中被删除临时 catalog 别名文件也会被清理保证多次运行无残留。四、测试套件的编写格式从零添加一个用例README 给出了新增测试套件的方法在cases/下创建一个 JSON 文件如cases/my_feature.json整体结构如下{ schema: server_to_client.json, tests: [ { description: Description of the test case, valid: true, data: { updateComponents: { ... } } }, { description: Should fail validation, valid: false, data: { ... } } ] }结合 run_tests.py 的run_suite()实现各字段的语义如下字段类型说明schemastring指定本次套件针对的 Schema 文件名必须在SCHEMAS映射中注册可选值server_to_client.json、common_types.json、catalog.json、client_to_server.jsontestsarray用例列表每条用例至少包含description、valid、data三个字段descriptionstring用例说明缺省时运行器以Test #序号代替validboolean期望的校验结果true表示该数据应当通过校验false表示应当被拒绝dataobject待校验的实际消息负载会与指定的 Schema 进行比对运行器对每条用例的逻辑是将data写入临时文件 → 调用validate_ajv()得到实际校验结果 → 与valid期望值比对一致则计数为 pass不一致则打印[FAIL]及期望值/实际值差异并输出 ajv 的详细错误信息。五、典型校验模式一组件结构与 checks 验证Button、Tabs、Textcases/下最丰富的一类套件是对服务端到客户端消息中组件结构的验证尤其是 v0.9.1 中引入的checks条件校验机制。5.1 Button变体与校验规则button_checks.json 围绕 Button 组件覆盖了多个正反场景合法用例嵌套 checks 逻辑使用and/or组合布尔表达式验证必须同意条款且提供邮箱或电话的表单门控{ id: btn1, component: Button, child: txt1, action: {event: {name: submit}}, checks: [ { condition: { call: and, args: { values: [ {call: required, args: {value: {path: /formData/terms}}, returnType: boolean}, {call: or, args: {values: [ {call: required, args: {value: {path: /formData/email}}, returnType: boolean}, {call: required, args: {value: {path: /formData/phone}}, returnType: boolean} ]}, returnType: boolean} ] }, returnType: boolean }, message: Must accept terms and provide contact info } ] }反面用例揭示了几类典型错误使用已废弃的enabled属性enabled: {path: /some/path}应失败——v0.9.1 已将其替换为 checks 机制checks 条件中的returnType必须是合法类型如boolean写成not_a_valid_type应失败checks 对象中不允许出现额外属性extraPropadditionalProperties约束会将其拒绝已废弃的布尔属性primary: true应失败取而代之的是variant: primary。5.2 Tabs 与 Text最小结构约束tabs_checks.json 验证 Tabs 组件的tabs数组非空约束minItems: 1空数组tabs: []应失败包含title与child的单个 tab 则通过。text_variants.json 验证 Text 组件的variant枚举白名单variant: h1合法variant: not_a_variant应失败。六、典型校验模式二可检查组件与表单验证函数checkable_components.json 将 checks 机制推广到所有可交互组件展示了表单验证函数的完整用法组件验证函数参数语义TextFieldrequiredvalue: {path}字段必填TextFieldemailvalue: {path}合法邮箱TextFieldregexvalue, pattern正则匹配如^\\d{10}$TextFieldlengthvalue, min, max长度区间如 8-64Slidernumericvalue, min, max数值区间ChoicePickerlengthvalue, min: 1至少选中一项min: 2, max: 2精确两项CheckBoxrequiredvalue: {path}必须勾选这些函数同样支持逻辑组合例如密码必须以字母开头或以数字开头的反例可表达为{ call: and, args: {values: [ {call: required, args: {value: {path: /formData/code}}, returnType: boolean}, {call: or, args: {values: [ {call: regex, args: {value: {path: /formData/code}, pattern: ^[A-Z]}, returnType: boolean}, {call: not, args: {value: {call: regex, args: {value: {path: /formData/code}, pattern: ^[0-9]}, returnType: boolean}}, returnType: boolean} ]}, returnType: boolean} ]}, returnType: boolean }反面用例还专门覆盖了结构性错误checks 缺少必填的message字段应失败check 条件使用了非布尔returnType如formatString返回string却被用于条件应失败。七、典型校验模式三函数目录调用校验function_catalog_validation.json共 40 条用例系统验证了函数目录中每个内置函数调用的参数签名与返回类型约束是理解 v0.9.1 表达式系统的最佳素材布尔类函数required(value)参数缺失args: {}、参数过多args带extra字段、returnType非boolean均失败regex(value, pattern)缺少pattern、pattern类型错误数字、returnType非boolean均失败email(value)出现额外参数extra失败length(value, min?, max?)min/max必须为数字字符串5、负数-2失败两者都缺空对象失败numeric(value, min?, max?)min/max字符串类型失败and/or(values)values至少需要 2 个元素单个元素失败returnType非boolean失败not(value)参数类型错误字符串true、returnType非boolean失败。格式化与字符串类函数用于Text.text等属性返回stringformatString(value)模板字符串Hello ${/name}合法value非字符串数字123失败formatNumber(value, decimals?, grouping?)decimals必须为数字字符串2、布尔true失败formatCurrency(value, currency)缺少currency失败currency必须为字符串数字840失败formatDate(value, format)format为null失败pluralize(value, one, other)缺少other失败。动作类函数用于action.functionCall返回voidopenUrl(url)args必须是对象字符串直接作为 args 失败url必须是合法 URInot a uri失败returnType必须为voidboolean失败。这些用例共同印证了一个事实v0.9.1 的函数调用是强类型的——每个函数的参数个数、参数类型与返回类型都在 Schema 中被显式约束任何偏离都会在校验阶段被拒绝。八、主题校验与客户端消息校验8.1 createSurface 主题校验theme_validation.json 验证createSurface消息中theme对象的规则primaryColor必须为字符串且是合法十六进制颜色#00BFFF通过123数字、invalid-color均失败额外主题属性如customProperty允许存在——这与server_to_client.json中 theme 引用目录中宽松的additionalProperties设计一致方便自定义主题扩展。8.2 客户端到服务端消息校验client_messages.json 面向client_to_server.jsonSchema验证从渲染客户端发回 Agent 的事件合法 action 消息与 client_to_server.json 中action定义一致五个必填字段name、surfaceId、sourceComponentId、timestamp、context齐全{ version: v0.9, action: { name: submit, surfaceId: main, sourceComponentId: btn_submit, timestamp: 2023-10-27T10:00:00Z, context: {foo: bar} } }合法 error 消息code取VALIDATION_FAILED配合surfaceId、pathJSON Pointer如/components/0/text与message描述校验失败位置。反面用例使用旧字段名updateDataModel的客户端消息应失败——v0.9.1 协议约定客户端只允许发送action或error两种消息client_to_server.json通过minProperties: 2, maxProperties: 2约束消息体只含version加一个事件字段。九、JSONL 流式端到端样例完整对话生命周期cases/目录中除了 JSON 套件还有一个特殊的 contact_form_example.jsonl它以JSON Lines格式按行存储了 4 条服务端消息模拟一次完整的联系表单会话createSurface创建contact_form_1表面并声明使用 Basic Cataloghttps://a2ui.org/specification/v0_9/catalogs/basic/catalog.jsonupdateComponents一次推送完整组件树——Card包裹Column内部包含标题行、姓名双栏weight: 1均分、带required/emailchecks 的邮箱字段、带regexchecks 的电话字段、互斥选择的ChoicePicker、分隔线、订阅CheckBox与主操作Button其action.event.context中还嵌套了formatDate函数调用与数据绑定{path: /contact/subscribe}updateDataModel将/contact路径下的数据模型整体更新为用户提交的完整表单值deleteSurface会话结束删除表面。在 run_tests.py 中validate_jsonl_example()逐行读取该文件将每一行作为一个独立 JSON 文档与server_to_client.json校验跳过空行任一行失败都会计为 FAIL 并输出对应行号。值得注意的是其中checks条件内部省略了returnType字段如{call:required,args:{...}}而这类写法在 JSON 套件中通常会被判为失败——这说明校验通过与否还取决于 Schema 中required属性列表的定义细节也提醒使用者在编写用例时务必先核对目标 Schema 的精确约束详见下一节。十、Schema 证据server_to_client 的消息骨架要准确编写用例必须回到 Schema 源头确认约束细节。server_to_client.json 定义了一个oneOf顶级结构服务端消息必须是以下四类之一CreateSurfaceMessage必填createSurface与version枚举[v0.9, v0.9.1]createSurface内必填surfaceId、catalogId可选theme引用catalog.json#/$defs/theme与sendDataModel布尔默认 false重复对同一surfaceId发送 createSurface 属协议错误必须先 deleteSurfaceUpdateComponentsMessage必填updateComponents与version组件列表minItems: 1且组件树中必须有且仅有一个id为root的组件作为根节点每个组件引用catalog.json#/$defs/anyComponentUpdateDataModelMessage通过surfaceIdpathvalue更新数据模型DeleteSurfaceMessage通过surfaceId删除表面。所有消息都带additionalProperties: false即未知字段会被直接拒绝——这正是多个反面用例废弃enabled、额外extraProp、旧updateDataModel字段名被判失败的根本原因。从源码结构看这套消息骨架与 docs/reference/messages.md、specification/v0_9_1/docs/a2ui_protocol.md 中描述的消息模型保持一致测试框架实质上充当了规范文本到可执行契约之间的翻译器。十一、最佳实践将测试框架接入开发与 CI 流程结合本仓库的既有设施可以归纳出以下实践建议协议演进时的回归守卫每当新增组件、函数或消息类型时先在cases/下新增套件正例验证合法结构、反例验证废弃字段与类型错误再运行测试框架确认 Schema 改动没有破坏既有行为利用退出码接入 CIrun_tests.py在存在失败用例时以非零退出码结束可直接嵌入 Git 钩子或 CI 流水线仓库根目录的 e2e_test.sh 等脚本也体现了类似脚本化校验 退出码门禁的思路目录内容即规范的可执行版本cases/与json/配合使得规范演进v0.8 → v0.9 → v0.9.1 → v1.0可对比 specification/v1_0/test/cases/拥有一致的验证口径——每个版本的协议变更都会留下可运行、可追溯的测试痕迹多语言 SDK 的一致性标尺仓库内 agent_sdks/python/a2ui_core、dart/a2ui_core、swift/core 等多个实现均以同一套 JSON Schema 为基准本测试框架即为它们提供协议黄金样本。十二、快速速查完整命令与目录清单操作命令 / 路径安装测试依赖cd specification/v0_9_1/test yarn install运行全部测试python3 specification/v0_9_1/test/run_tests.py通过 Yarn 脚本运行cd specification/v0_9_1/test yarn test服务端 Schemaspecification/v0_9_1/json/server_to_client.json客户端 Schemaspecification/v0_9_1/json/client_to_server.json组件目录含 theme 定义specification/v0_9_1/catalogs/basic/catalog.json测试用例目录specification/v0_9_1/test/cases/运行器实现specification/v0_9_1/test/run_tests.py这套Schema 定义 Python 运行器 ajv 校验器 JSON/JSONL 用例的测试体系是 A2UI v0.9.1 协议质量保障的核心环节它既守护了服务端消息的组件结构与表达式合法性也约束了客户端事件的字段契约同时还以可运行的端到端样例把整个建表面 → 渲染组件 → 更新数据 → 清理表面的会话生命周期固化下来让任何一端实现的改动都能被快速、自动、可重复地验证。【免费下载链接】a2ui项目地址: https://gitcode.com/GitHub_Trending/a2/a2ui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考