当文档失效时:使用 AI 的暴力规范发现
Source: Dev.to
请提供您希望翻译的完整文本内容(除代码块和 URL 之外),我将按照要求将其翻译成简体中文并保留原有的格式。
问题:未记录的行为
我需要将一个基于 LINQ 的查询库从 ksqlDB 移植到 Apache Flink SQL。
挑战不在代码本身,而在于两个平台都没有完整记录哪些功能可用、哪些不可用,以及当出现问题时的替代方案。
- ksqlDB 有
LEN(s)。Flink 没有——它使用CHAR_LENGTH(s)。 - ksqlDB 有
DATEADD。Flink 使用TIMESTAMPADD或区间运算。 - ksqlDB 的
JSON_EXTRACT_STRING在 Flink 中对应JSON_VALUE。 - 有些函数两边都有,但行为不同。
文档只覆盖了理想情况。生产环境需要完整的映射。
人类方法:不可持续
手动测试的步骤如下:
- 选择一个函数
- 编写测试查询
- 在 Flink 上运行
- 记录成功/失败
- 若失败,搜索替代方案
- 对每个函数 × 数据类型 × 子句组合重复上述过程
对于 50 多个函数、10 多种数据类型以及 5 种子句上下文(SELECT、WHERE、GROUP BY、HAVING、JOIN),你将面对成千上万的组合。
- 所需时间: 数周。
- 所需耐心: 超乎常人。
AI 方法:暴力发现
我给 AI 下了一个简单指令:
- 调查哪些查询可以在 Flink SQL 中使用。
- 测试数据类型和函数的组合。
- 覆盖 SELECT、WHERE、GROUP BY、HAVING 和 JOIN。
没有详细的测试计划,也没有列举案例。AI 生成组合,在 Docker 化的 Flink 环境中执行,记录结果,并在出现错误时探索替代方案。
结果:方言映射
在系统化探查后,得到如下完整映射:
| Function | ksqlDB | Flink | Status |
|---|---|---|---|
| 字符串长度 | LEN(s) | CHAR_LENGTH(s) | ksqlDB 形式 NG |
| 字符串拆分 | SPLIT(s, d) | SPLIT_INDEX(s, d, i) | ksqlDB 形式 NG |
| 日期加法 | DATEADD(unit, n, ts) | TIMESTAMPADD(UNIT, n, ts) | ksqlDB 形式 NG |
| JSON 提取 | JSON_EXTRACT_STRING | JSON_VALUE | ksqlDB 形式 NG |
| 正则匹配 | REGEXP_LIKE | SIMILAR TO | ksqlDB 形式 NG |
| 填充 | LPAD/RPAD | LPAD/RPAD | OK |
| 空值处理 | COALESCE/NULLIF | COALESCE/NULLIF | OK |
| 安全转换 | N/A | TRY_CAST | 仅 Flink 支持 |
文档未提及的边缘情况
JSON_QUERY在某些环境下对数组元素访问会返回NULL。LIKE子句中的ESCAPE '\\'失效;请改用ESCAPE '^'。- 数组索引为 1 基;
arr[0]会抛出错误。 SESSION窗口在流式模式下可用,但在批处理模式下会失败。- 将保留字用作别名(例如
AS Values)会导致解析错误。
速度:决定性的优势
| 方法 | 时间 | 覆盖范围 |
|---|---|---|
| 手动 | 周 | 部分,受疲劳限制 |
| AI 驱动 | 小时 | 全面 |
AI 不会感到疲倦。AI 不会因为是星期五下午而跳过边缘情况。AI 以与第一次相同的勤勉度运行第 47 次 JSON 函数测试。速度优势不是渐进的——而是范畴性的。
What This Changes
传统的端到端(E2E)测试假设你已经了解规范并在验证实现。这颠倒了模型:将 E2E 视为规范发现。当外部系统的文档不完整时,AI 驱动的暴力测试成为获取真实情况的最快途径。
人类角色
AI 处理了组合爆炸。我的角色是:
- 定义轴线: 数据类型、函数、子句上下文
- 提供环境: 用于执行的 Docker 化 Flink
- 评估结果: OK/NG/备选映射
- 做出设计决策: 支持哪些模式,哪些要快速失败
这些发现直接用于我库中的方言抽象层——准确了解 ksqlDB 与 Flink 的分歧点,使得可以在编译时进行清晰的分离,而不是在运行时出现意外。
结论
当文档失效时,暴力破解获胜。AI 将端到端测试从验证活动转变为发现活动。使得穷尽人工测试不可能的组合爆炸,成为 AI 的自然工作模式。
此测试方法是在创建 Kafka.Context.Streaming 时开发的,它是一个支持多种 SQL 方言的查询抽象层。