OperationSequence DSL 2.1 语法规范

概述

OperationSequence (简称 OS) DSL 2.1 是一个基于 Read/Write/Ensure 序列的声明式操作与验证 DSL。它将所有操作抽象为三种核心动作:

  • read: 读取数据(对应 HTTP GET / SQL SELECT / S3 SELECT 等)
  • write: 写入或变更数据(对应 HTTP POST/PUT/PATCH/DELETE / SQL INSERT/UPDATE/DELETE 等)
  • ensure: 断言数据符合预期,失败则中止

在此抽象之上,2.1 版本增强了 JSON 数据处理能力,支持原生 JSON 字面量和 Python 风格的三引号字符串,使脚本对初级测试人员和 AI 生成场景都更加友好。

采用两阶段执行模型:

  • declare-block: 声明阶段,加载配置、声明服务和定义变量
  • action-block: 执行阶段,按 read/write/ensure 序列执行具体操作

一、Declare-Block(声明块)

声明块位于脚本开头,负责配置加载、服务声明和变量定义。

1.1 配置文件加载

config <config_file_path>

说明:

  • 加载外部配置文件(JSON/YAML 格式)
  • 可多次加载,后加载的配置会覆盖之前的同名配置
  • 配置文件必须存在,否则报错终止

示例:

config ./config/dev.json
config ./config/secrets.json

1.2 数据服务声明

data-service <service_name>

说明:

  • 声明要使用的数据服务
  • <service_name> 必须在已加载的配置文件中定义
  • 未定义的服务会导致执行终止

示例:

data-service mysql_db
data-service sqlite_cache
data-service postgres_main

1.3 HTTP 服务声明

http-service <service_name>

说明:

  • 声明要使用的 HTTP 服务
  • <service_name> 必须在已加载的配置文件中定义
  • 未定义的服务会导致执行终止

示例:

http-service user_api
http-service product_api

1.4 变量声明

var <variable_name> = <value>

说明:

  • 声明具名变量并赋值
  • 变量可使用字面值、内置函数、环境变量或原生 JSON
  • 变量在后续操作中通过 @{variable_name} 引用

示例:

var user_id = "U001"
var user_name = random_name()
var password = random_password()
var age = random_int(18, 65)
var amount = random_float(10.0, 1000.0)

// v2.1 新增:原生 JSON 字面量
var profile = {"level":"gold","score":8800}

// v2.1 新增:多行 JSON
var product = {
    "name": "机械键盘",
    "price": 599.00,
    "tags": ["电子", "外设", "热卖"]
}

// v2.1 新增:三引号字符串
var longText = """多行文本内容"""

1.5 原生 JSON 字面量支持(v2.1 新增)

语法:

var <name> = {<json_object>}
var <name> = [<json_array>]

说明:

  • 变量赋值时支持直接书写 JSON 对象/数组,无需字符串包裹和转义
  • {[ 开头的赋值内容自动解析为 JSON
  • JSON 字面量可跨多行书写,缩进由解析器自动忽略

示例:

// 单行 JSON
var order = {"productId":"P001","quantity":2}

// 多行 JSON
var order = {
    "productId": "P001",
    "quantity": 2,
    "shipping": {
        "address": "北京市朝阳区",
        "method": "express"
    }
}

1.6 三引号字符串(v2.1 新增)

语法:

var <name> = '''<content>'''
var <name> = """<content>"""

说明:

  • 支持多行字符串,保留原始格式
  • 单引号 ''' 和双引号 """ 等价
  • 常用于定义超长文本或 JSON 字符串

示例:

var jsonData = '''{
    "productId": "P001",
    "quantity": 2
}'''

var article = """欢迎来到 OperationSequence DSL。
这是一个专注于 Read/Write/Ensure 序列的声明式测试语言。
无论底层是 HTTP、数据库还是对象存储,都可以用统一的原语描述。"""

1.7 JSON 内变量嵌入(v2.1 新增)

语法:

var product_id = "P001"
var order = {
    "productId": @{product_id}
}

说明:

  • 在 JSON 字面量中,@{var_name} 会被自动替换为对应变量值
  • 字符串类型变量自动添加引号

1.8 内置随机函数

random_int(min, max)

生成指定范围内的随机整数

var user_age = random_int(18, 65)
var order_no = random_int(1000, 9999)
random_float(min, max)

生成指定范围内的随机浮点数

var price = random_float(0.01, 99.99)
var amount = random_float(10.0, 1000.0)
random_name()

生成随机用户名

var user_name = random_name()
random_password()

生成随机密码

var password = random_password()
random_string(length)

生成指定长度的随机字符串

var session_id = random_string(32)
var token = random_string(16)

二、Action-Block(执行块)

执行块包含具体的操作指令。所有指令均可归类为 read / write / ensure 三种核心动作。

指令统一格式:SERVICE VERB [TARGET] BODY [HEADER]

2.1 数据操作(CRUD)

所有 CRUD 动词本质都是 read / write 的具体形式:

  • insert / update / deletewrite
  • select / queryread
INSERT - 写入数据
<service> insert <table> <json_body>

示例:

mysql_db insert products {"product_id": "@{product_id}", "name": "机械键盘", "price": 599.00}
SELECT - 读取数据
<service> select <table> [where <condition>]

示例:

mysql_db select products where product_id = '@{product_id}'
sqlite_cache select sessions
UPDATE - 更新数据
<service> update <table> <json_body> [where <condition>]

示例:

mysql_db update products {"price": 499.00} where product_id = '@{product_id}'
DELETE - 删除数据
<service> delete <table> [where <condition>]

示例:

mysql_db delete products where product_id = '@{product_id}'
SQL 直接查询
<service> query <sql_statement>

示例:

mysql_db query SELECT COUNT(*) FROM products WHERE status = 'on_sale'

2.2 HTTP 请求

HTTP 的 get/post/put/delete/patch 同样可归为 read / write:

  • getread
  • post / put / patch / deletewrite
<service> <http_method> <path> [json_body] [headers]

HTTP 方法: GET, POST, PUT, DELETE, PATCH

示例:

user_api get /users/@{user_id}
product_api post /orders {"productId": "@{product_id}", "quantity": 2}
user_api put /users/@{user_id} {"nickname": "alex_updated"} headers {"Authorization": "Bearer @{token}"}

2.3 结果捕获

capture <expression> as <variable_name>

说明: 将执行结果保存到变量,供后续使用

示例:

user_api get /users/@{user_id}
capture result.user_name as api_username
capture result.status as user_status

2.4 断言校验(Ensure)

ensure <expression>

说明: 验证表达式是否为真,失败则终止执行。这是 OperationSequence 的核心 —— 通过断言保证 read/write 操作后的系统状态符合预期。

示例:

user_api get /users/@{user_id}
ensure result.user_name == '@{user_name}'
ensure result.status == 'active'
ensure result.level == 'gold'
ensure $status == 200

2.5 变量引用

使用 @{variable_name} 引用已声明或已捕获的变量

示例:

var uid = random_string(8)
user_api get /users/@{uid}
capture result.user_id as captured_uid

mysql_db select orders where user_id = '@{captured_uid}'
ensure result[0].status == 'completed'

2.6 输出打印

echo <text>

说明: 输出文本信息,用于调试和日志

示例:

echo "Starting user verification..."
user_api get /users/@{user_id}
echo "User: @{user_name} verified successfully"

2.7 注释

// 单行注释
/* 多行注释 */

三、配置文件格式

配置文件采用 JSON 格式,包含数据源和 HTTP 服务定义。

3.1 完整配置示例

{
  "data-services": {
    "mysql_db": {
      "type": "mysql",
      "host": "127.0.0.1",
      "port": 3306,
      "database": "test_db",
      "username": "${MYSQL_USER}",
      "password": "${MYSQL_PASS}"
    },
    "sqlite_cache": {
      "type": "sqlite",
      "path": "./data/cache.db"
    },
    "postgres_main": {
      "type": "postgresql",
      "host": "127.0.0.1",
      "port": 5432,
      "database": "app_db",
      "username": "${PG_USER}",
      "password": "${PG_PASS}"
    }
  },
  "http-services": {
    "user_api": {
      "base_url": "http://127.0.0.1:80/v1",
      "headers": {
        "Content-Type": "application/json",
        "X-App-Key": "${APP_KEY}"
      },
      "timeout": 30000
    },
    "product_api": {
      "base_url": "http://127.0.0.1:80",
      "headers": {
        "Authorization": "Bearer ${APP_TOKEN}"
      }
    }
  }
}

3.2 数据源类型

类型 说明 必需字段
mysql MySQL 数据库 host, port, database, username, password
sqlite SQLite 文件数据库 path
postgresql PostgreSQL 数据库 host, port, database, username, password
sqlserver SQL Server 数据库 host, port, database, username, password
csv CSV 文件 path

3.3 环境变量引用

配置文件中可使用 ${ENV_VAR} 格式引用环境变量。


四、完整脚本示例

4.1 电商商品与订单示例

// 加载配置文件
config ./config/config.json

// 声明要使用的服务
data-service mysql_db
http-service product_api
http-service order_api

// 声明测试变量(使用随机函数生成测试数据)
var product_id = random_string(8)
var product_name = "机械键盘 @{product_id}"
var price = random_float(300.0, 900.0)
var stock = random_int(100, 1000)
var quantity = random_int(1, 5)

// === Read/Write/Ensure 序列:商品上架 ===
echo "=== 步骤 1: 写入商品数据 ==="

// Write: 直接写入数据库,构造前置状态
mysql_db insert products {
    "product_id": "@{product_id}",
    "name": "@{product_name}",
    "price": @{price},
    "stock": @{stock},
    "status": "on_sale"
}

// Read: 通过 HTTP 读取,验证写入
product_api get /products/@{product_id}
capture result as fetched_product

// Ensure: 校验字段正确
ensure fetched_product.name == '@{product_name}'
ensure fetched_product.price == @{price}
ensure fetched_product.stock == @{stock}
ensure fetched_product.status == 'on_sale'
echo "商品创建并校验通过: @{product_name}"

// === Read/Write/Ensure 序列:创建订单 ===
echo "=== 步骤 2: 写入订单 ==="

// Write: 调用 HTTP 接口下单
order_api post /orders {
    "productId": "@{product_id}",
    "quantity": @{quantity}
}
capture result.orderId as order_id
ensure $status == 201

// Read: 查询订单状态
order_api get /orders/@{order_id}
ensure result.status == 'paid'
ensure result.totalAmount == @{price * quantity}

// Ensure: 校验数据库中的持久化事实
mysql_db query SELECT stock FROM products WHERE product_id = '@{product_id}'
capture result[0].stock as remaining_stock
ensure remaining_stock == @{stock - quantity}
echo "订单 @{order_id} 创建成功,库存更新为: @{remaining_stock}"

// === Read/Write/Ensure 序列:下架商品 ===
echo "=== 步骤 3: 更新商品状态 ==="

// Write: 数据库写入新状态
mysql_db update products {"status": "off_shelf"} where product_id = '@{product_id}'

// Read + Ensure: HTTP 读取并断言下架
product_api get /products/@{product_id}
ensure result.status == 'off_shelf'

echo "=== 所有 Read/Write/Ensure 序列通过 ==="

4.2 博客文章发布示例(v2.1 增强特性)

// 声明服务
data-service mysql_db
http-service blog_api

// 变量
var author_id = random_string(6)
var title = "OperationSequence DSL 入门指南"
var tags = ["技术", "测试", "DSL"]

// v2.1 原生 JSON + 变量嵌入
var article = {
    "title": "@{title}",
    "authorId": "@{author_id}",
    "tags": @{tags},
    "published": true
}

// Write: HTTP 发布文章
blog_api post /articles @{article}
capture result.articleId as article_id
ensure $status == 201
echo "文章已发布: @{article_id}"

// v2.1 三引号字符串 - 定义评论内容
var comment = '''这篇文章讲得很清楚,
Read/Write/Ensure 的抽象让所有协议统一了。
期待更多示例!'''

blog_api post /articles/@{article_id}/comments {"content": "@{comment}", "author": "alex"}
ensure $status == 200

// Read + Ensure: 读取文章评论数
blog_api get /articles/@{article_id}/comments
ensure result.total >= 1

// Write + Ensure: 直接更新数据库,模拟管理员置顶
mysql_db update articles {"is_top": 1} where article_id = '@{article_id}'
mysql_db select articles where article_id = '@{article_id}'
ensure result[0].is_top == 1

echo "文章发布与置顶流程验证通过"

五、执行流程

  1. 解析阶段: 读取脚本,识别 declare-block 和 action-block
  2. 配置加载: 按顺序加载所有 config 文件
  3. 变量解析: 解析 var 声明,执行内置函数生成变量值,支持原生 JSON 和三引号字符串
  4. 服务验证: 检查声明的服务是否在配置中存在
  5. 执行阶段: 按顺序执行 action-block 中的指令(本质是 read/write 序列)
  6. 断言校验: 每个 ensure 指令是 read/write 序列的终点,校验数据符合预期,失败则终止

六、内置函数列表

函数 参数 返回值 示例
random_int (min, max) 随机整数 var age = random_int(18, 65)
random_float (min, max) 随机浮点数 var price = random_float(1.0, 99.99)
random_name ([prefix]) 随机用户名 var name = random_name()
random_password () 随机密码 var pwd = random_password()
random_string ([prefix],[length=10]) 指定长度随机字符串 var sid = random_string(32)

七、核心理念

OperationSequence DSL 将所有操作统一为 Read / Write / Ensure 三种动作的有序序列:

  • Read:从系统中获取事实(HTTP GET / SQL SELECT)
  • Write:向系统写入或变更事实(HTTP POST/PUT/DELETE / SQL INSERT/UPDATE/DELETE)
  • Ensure:基于事实做出判定,是 Read/Write 序列的闭环

无论底层是 HTTP 接口、关系数据库还是对象存储,测试脚本始终围绕"写入 → 读取 → 断言"的模式组织。这种抽象使得:

  • 脚本结构对初级测试人员一目了然
  • AI 可以稳定地生成符合该结构的脚本
  • 审查者可以聚焦于事实判断,而非语法细节
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐