测试与提取 Schema
测试与提取 Schema
Section titled “测试与提取 Schema”三种操作不同:viat script test 运行本地离线测试;viat script run NAME --args JSON 在服务器执行已保存的实时草稿;发布端点才冻结公共调用目标。离线通过或草稿成功都不会修改已发布端点。
最小 Python 离线用例
Section titled “最小 Python 离线用例”在已有本地项目保存 scripts/hello.py:
from viat import ctx
def main(name: str = "world"): ctx.logger.info("greet", who=name) return {"hello": name}保存 tests/test_hello.py:
from viat.testing import ctx_withfrom hello import main
def test_hello(): ctx_with() assert main(name="Ada") == {"hello": "Ada"}viat script test tests/test_hello.pyviat script test --json本地需要 uv、Python。CLI 构建含脚本 requirements 的临时 pytest 环境,将 scripts/、tests/ 加入导入路径。文件夹内 uses: 使用 from viat.testing import load,再调用 load("folder/name").main(...);平铺导入无法隔离不同文件夹的同名模块。
TypeScript 需要 Bun。对应 scripts/hello.ts 和 tests/hello.test.ts:
import { ctx } from "viat";export async function main(args: { name: string }): Promise<{ hello: string }> { ctx.logger.info("greet", { who: args.name }); return { hello: args.name };}import { test, expect } from "bun:test";import { ctxWith } from "viat/testing";import { main } from "../scripts/hello";test("hello", async () => { ctxWith({}); expect(await main({ name: "Ada" })).toEqual({ hello: "Ada" });});viat script test tests/hello.test.ts运行器按找到的语言选择 pytest、Bun 和 Rust #[cfg(test)] 测试,不是通用 SQL/shell/LLM 解释器。缺失本地工具是未满足前置条件,不能算测试通过。
替身、权限与副作用
Section titled “替身、权限与副作用”测试 host 用固定数据回答真实资源 RPC。支持 HTTP、GraphQL、cloud、secret、config、托管存储与 PostgreSQL 等替身。TestDb(url) 使用真实的临时 PostgreSQL 数据库,每个测试包裹在回滚事务中,broker 事务用 savepoint 模拟。因此并非完全无网络,绝不能指向生产。单连接不能忠实复现并发重叠事务。
ctx_with(resources={...}, request={...}, principal={...}) / ctxWith({...}) 提供上下文。涉及授权、用户管理、WebSocket 时使用 FakeAuthz/FakeProjectUsers/FakeWs;宽松或缺失的替身不能证明生产授权正确。不支持的 helper 会失败,不会偷偷访问真实资源。1.1.0 尚未覆盖 MySQL、S3 和事务内 GraphQL。Cassette 记录/重放 HTTP 型 I/O,不代表所有协议。
ctx.tasks.enqueue 记录到 ctx.tasks.enqueued,get/cancel 操作记录器,ctx.cache.purged 记录清除请求。只有离线测试如此。服务器草稿/Test 可真实发送邮件、push、消息、写 secret 和创建任务。viat script run hello --record cassettes 本身也是真实执行;需要明确同意,并检查 cassette 中是否含敏感业务数据。
| 语言 | 输入/输出提取及限制 |
|---|---|
| Python | 解析 main 注解、默认值和支持的本地类型结构。缺失/不支持的注解使字段开放并可能警告;Optional[T]、T | None、默认 None 接受 null。返回注解不能证明所有运行时返回。 |
| TypeScript | 优先 export function main(args: { ... }): Promise<{ ... }>;支持基本类型、数组、对象字面类型和联合。命名/导入/复杂类型可退化为 {},不是全程序类型检查。可选属性不等于可空。运行时可接受默认导出,但提取器寻找具名 main 声明。 |
| SQL | :name 配合 -- @input name:type[=default];未注解占位符默认必填 string 并警告。输出只有 rows/affected 结构,不含精确列。提取扫描器比实际 SQL 绑定简单,特殊 cast/dollar quote 可能产生误导性参数。 |
| Shell | 头部 # @input;无法静态提取输出,总有警告。默认值为字符串。 |
| GraphQL | 只取第一个操作的变量,多操作警告。自定义 scalar/enum/input object 不展开。提取输出描述 data/errors 信封,但真实运行器只返回 data,不能当作观察结果。 |
viat_gql | 尚不支持提取,开放 Schema 并警告。数据库 Schema 内省是另一回事。 |
llm | {{name}} 形成必填 string 输入;输出 content/model/usage,不验证模型事实正确性。 |
| Rust | 编译后运行 --viat-schema;serve_typed 提供 serde/schemars Schema。保存会清空,编译/发布刷新。Untyped serve 没有类型化 Schema。 |
| Binary | 不提取 I/O Schema、不运行 Schema 探测;端点输入开放,但必须满足进程协议。 |
提取失败通常是警告/开放 Schema,不是统一拒绝源码。检查 schema_warnings 与保存的 Schema,再验证端点绑定和拒绝行为。不能假设 JSON Schema 默认值会填充缺失输入;工作流引擎会显式应用工作流输入默认值,见工作流语法。
草稿、发布与清理命令
Section titled “草稿、发布与清理命令”执行前先完成实例认证,再选择隔离项目。ENDPOINT_ID 替换为创建返回的 ID,不是名称参数。
viat script create --name hello --language python --file scripts/hello.pyviat script update hello --file scripts/hello.pyviat script run hello --args '{"name":"Ada"}'viat endpoint create --segment hello --method POST --script helloviat endpoint publish ENDPOINT_IDviat script logs helloviat endpoint unpublish ENDPOINT_IDviat endpoint delete ENDPOINT_IDviat script delete hello预期脚本正文为 {"hello":"Ada"},script run 将成功输出美化为 JSON 打印到 stdout,诊断 stderr 单独显示。发布可能因警告或测试门槛拒绝,应修复,不要自动确认。CLI 不绕过项目成员、编辑权限或公共端点认证。删除是真实操作,不属于离线测试。本文没有执行测试或真实服务调用。