#api-testing #yaml #env-var #scenario #json #syntax #dsl

bin+lib testkit

测试领域特定语言 (DSL)。从 API 和浏览器自动化开始。

5 个版本

0.1.5 2024 年 8 月 7 日
0.1.4 2024 年 7 月 30 日
0.1.3 2024 年 7 月 29 日
0.1.2 2024 年 5 月 1 日
0.1.1 2024 年 4 月 30 日

#253Web 编程

Download history 260/week @ 2024-04-28 35/week @ 2024-05-05 9/week @ 2024-05-12 23/week @ 2024-05-19 4/week @ 2024-05-26 16/week @ 2024-06-02 2/week @ 2024-06-09 2/week @ 2024-06-16 17/week @ 2024-06-23 21/week @ 2024-06-30 2/week @ 2024-07-07 1/week @ 2024-07-14 262/week @ 2024-07-28 124/week @ 2024-08-04 40/week @ 2024-08-11

每月 426 次下载

MIT/Apache

71KB
1K SLoC

Testkit

APItoolkit OSS Join Discord Server

Testkit 是由 APItoolkit 团队和杰出的社区 贡献者 开发的一款用于 API 手动测试和自动化测试任务的工具。Testkit 提供了一种简化的 YAML 语法来定义和执行 API 测试场景。

Testkit demo


目录


为什么需要一个测试 DSL?

  • 团队不应该因为想测试一个 Web 系统的 API 就被迫编写 JavaScript (Postman)、Groovy (Katalon) 或 Java (Rest-Assured)。
  • 我们应该能够创建交互式构建器,生成这个底层的 DSL(领域特定语言)。因此,你甚至不需要在未来手动编写这个 DSL。
  • 我们应该能够使用相同的脚本来进行单个测试和负载测试。
  • 我们仍然能够在版本控制中持久化这些测试,并与同事协作。
  • 受到 本地优先软件 原则的启发。

安装

要安装 testkit,请按照以下选项之一操作(点击切换)

下载二进制文件

转到 发布页面,下载适用于您操作系统的最新版本的 testkit 二进制文件(Windows、macOS 或 Linux),然后继续安装。

二进制文件 描述
testkit-发布-测试-i686-pc-windows-msvc.zip 32 位 Windows (MSVC)
testkit-发布-测试-x86_64-pc-windows-msvc.zip 64 位 Windows (MSVC)
testkit-发布-测试-x86_64-pc-windows-gnu.zip 64 位 Windows (GNU)
testkit-发布-测试-x86_64-apple-darwin.tar.gz 64 位 macOS (Darwin)
testkit-发布-测试-x86_64-unknown-linux-gnu.tar.gz 64 位 Linux (GNU)

下载后,提取 zip 文件并继续安装提取的文件。或者,如果您使用 macOS,可以使用 Homebrew 进行安装,如下所示

  1. 使用以下命令将 testkit 发布仓库添加为 Homebrew 公式源的切换

    brew tap apitoolkit/testkit
    
  2. 使用以下命令安装 testkit

    brew install testkit
    
克隆仓库

请按照以下步骤在本地构建项目

  1. 确保您的计算机上已安装 Rust 编程语言和 Cargo 包管理器

  2. 使用以下命令从 GitHub 克隆 testkit 仓库

    git clone https://github.com/testkit/testkit
    
  3. 使用以下命令打开克隆的目录

    cd testkit
    
  4. 使用以下 Cargo 命令构建项目

    cargo build --release
    
  5. 构建过程完成后,您将在 target/release 目录下找到 testkit 可执行文件。

  6. 使用以下命令运行 testkit CLI 工具

    testkit test --file ./test.tk.yaml
    
  7. 为了进一步测试,请确保将 ./test.tk.yaml 替换为您 YAML 测试文件的路径。


[注意]

成功安装 testkit 后,运行 testkit --help 命令以获取所有 CLI 命令和选项。

与其他测试库的比较

在深入了解 testkit 及其功能之前,让我们将其与其他测试库进行比较,以突出其优雅、简洁和简单。通过展示差异,您将看到 testkit 如何提供更流畅、更用户友好的 API 测试方法。为了说明这一点,我们将重写以下 Cypress 测试

Cypress ⤵️

describe('TODO API testing', () => {
  let todoItem;
  it('fetches Todo items - GET', () => {
    cy.request('/todos/').as('todoRequest');
    cy.get('@todoRequest').then((todos) => {
      todoItem = todos.body[0]['_id'];
      expect(todos.status).to.eq(200);
      assert.isArray(todos.body, 'Todos Response is an array');
    });
  });

  it('Deletes Todo items - DELETE', () => {
    cy.request('DELETE', `/todos/${todoItem}`).as('todoRequest');
    cy.get('@todoRequest').then((todos) => {
      expect(todos.status).to.eq(200);
      assert.isString(todos.body, 'todo deleted!');
    });
  });

  it('Adds Todo item - POST', () => {
    cy.request('POST', '/todos/', { task: 'run tests' }).as('todoRequest');
    // Adds new Todo item by defining Todo name
    cy.get('@todoRequest').then((todos) => {
      expect(todos.status).to.eq(200);
      cy.wrap(todos.body).should('deep.include', {
        task: 'run tests',
        completed: false,
      });
    });
  });
});

Testkit ⤵️

---
    - title: fetches TODO items - GET
      GET: /todos/
      asserts: # Asserts accepts a list of expressions, usually via JSONPaths to identify the items being referred to.
        - ok: $.resp.status == 200  # Rely on an expressions library for parsing expressions
        - array: $.resp.json
      exports: # Values which should be accessible to future steps.
        todoItem: $.resp.json[0]._id

    - title: deletes TODO items - DELETE
      DELETE: /todos/$.stages[0].todoItem # Relative syntax exists: $.stages[-1].todoItem, -1 means one stage before me
      asserts:
        - empty: $.resp.json.todos
        - string: $.resp.json

    - title: Adds Todo item - POST
      POST: /todos/
      json:
        task: "run tests"
      asserts:
        - ok: $.resp.status == 200
        - ok: $.resp.json.task == "run tests"
        - ok: $.resp.json.completed == false

Testkit 提供了一种干净直观的语法,简化了定义和执行 API 测试场景的过程。

测试定义语法

Testkit 使用基于 YAML 的语法来定义测试场景。每个场景由多个阶段组成,其中每个阶段代表一个特定的 API 请求及其关联的断言。以下是定义 API 测试的 YAML 语法的示例

---
    - title: fetches TODO items - GET
      GET: /todos/
      asserts:
        - ok: $.resp.status == 200
        - array: $.resp.json
      exports:
        todoItem: $.resp.json[0]._id

    - title: deletes TODO items - DELETE
      DELETE: /todos/$.stages[0].todoItem
      asserts:
        - empty: $.resp.json.todos
        - string: $.resp.json

    - title: Adds Todo item - POST
      POST: /todos/
      json:
          task: "run tests"
      asserts:
        - ok: $.resp.status == 200
        - ok: $.resp.json.task == "run tests"
        - ok: $.resp.json.completed

在上面的示例中,YAML 测试文件定义了三个测试项:使用 GET 请求获取 TODO 项、使用 DELETE 请求删除特定的 TODO 项以及使用 POST 请求添加新的 TODO 项。YAML 文件由一系列测试场景组成。每个场景代表一个 API 请求,并包含以下字段

字段 描述
title (必需) 阶段的描述性名称。
request (必需) 定义要发出的 API 请求,包括 HTTP 方法和 URL。
asserts (可选) 可选。定义要执行以验证响应的断言。
exports (可选) 可选。指定要从响应中捕获的值,供后续阶段使用。

请点击以下每个切换按钮,以了解更多关于每个字段的信息。

request 字段

testkit 中,request 字段定义要发出的 API 请求,并包含三个属性

  1. method (必需):此属性指定请求的 HTTP 方法,例如 GETPOSTPUTDELETEmethod 属性的值是请求的 URL 路径。示例
# POST request
- title: Adds Todo item - POST
  POST: /todos/

# GET request
- title: Fetches Todo items - GET
  GET: /todos/
  1. headers (可选):此属性允许您在请求中包含 HTTP 头。头可以用于向服务器传递额外的信息,例如身份验证令牌或内容类型。示例
- title: Fetches Todo items - GET with headers
  GET: /todos/
  headers:
    Authorization: Bearer <token>
    Content-Type: application/json
    Allowed-Methods:
      - GET
      - POST
  1. json (可选):此属性允许在必要时在请求中包含 JSON 格式的请求体数据。通过在 request 字段中指定 json 属性,您可以为 API 请求提供需要发送的格式化数据。示例
- title: Create User - POST
  POST: /users/
  json:
    name: John Doe
    age: 25
    email: [email protected]

在上面的例子中,通过POST请求创建新用户。属性json包含用户数据的JSON格式,包括诸如nameageemail等属性。在request字段中包含json属性,您可以将结构化数据传递给API端点,从而便于在服务器上创建或更新资源。

request字段中的这些属性提供了在测试过程中对API请求的灵活性和控制。您可以指定HTTP方法,并在需要时包含头信息,以有效地与API端点交互。

asserts字段

testkit中的asserts字段在定义要在API响应上执行的断言或验证中起着至关重要的作用。它允许您指定测试成功通过必须满足的条件。该字段接受一个键值对集合,其中键代表断言类型(可以将其视为变量),值定义了要评估的相应表达式或条件。您可以在asserts字段中包含多个断言,以对API响应的不同方面执行各种验证,例如检查特定属性、验证某些数据的存在,或比较值。

以下是使用asserts字段的示例

- title: Fetches Todo items - GET
  GET: /todos/
  asserts:
    - ok: $.resp.status == 200
    - array: $.resp.json
    - ok: $.resp.json[0].task == "run tests"

注意:在.json$.resp.json告诉testkit将响应转换为JSON格式。这允许您使用JSONPath表达式访问响应JSON的属性。

在上面的例子中,我们定义了三个断言

  1. ok:这个断言检查响应状态码是否等于200。表达式$.resp.status == 200将被评估,如果它返回true,则断言被认为是成功的。

  2. array:这个断言验证响应体是否为数组。表达式$.resp.json将被评估,如果结果是数组,则断言被认为是成功的。

  3. ok:这个断言检查从API响应中检索到的第一个待办事项是否有一个任务名称等于"run tests"。表达式$.resp.json将被评估,如果它返回true,则断言被认为是成功的。

通过有效地利用asserts字段,您可以确保API响应符合预期标准,从而对API的正确性和可靠性充满信心。您可以使用的所有可能的断言如下

断言 描述
ok 检查提供的表达式是否评估为true
empty 检查一个值是否为空(例如,空数组、字符串或null)。
array 检查一个值是否为数组。
string 检查一个值是否为字符串。
number 检查一个值是否为数字。
boolean 检查一个值是否为布尔值。
null 检查一个值是否为null。
exists 检查一个值是否存在。
date 检查一个值是否为有效的日期字符串。

这些断言提供了广泛的选择,用于验证API响应的不同方面,确保数据的正确性和完整性。您可以根据API测试场景的具体验证需求选择合适的断言。

exports 字段

testkit 中的 exports 字段允许您捕获并存储阶段的API响应值,以便在测试场景中未来参考。它提供了一种方便的方法来提取特定数据,并在测试的后续阶段使其可访问。

要使用 exports 字段,您定义键值对,其中键代表导出的名称(将其视为变量),而值定义用于从响应中提取所需数据的JSON路径或表达式。

以下是一个演示 exports 字段用法的示例

- title: Fetches Todo items - GET
  GET: /todos/
  exports:
    todoItem: $.resp.json[0]._id

在上面的示例中,exports 字段捕获了API响应数组中第一个元素的 _id 属性的值。它将此值分配给 todoItem 导出。通过在 todoItem 导出中捕获 _id 值,您可以在测试场景的后续阶段访问它。这允许您使用提取的数据进行进一步的API请求、断言或任何其他必要的操作。

exports 字段使您能够在测试场景的不同阶段之间创建桥梁,提供在它们之间传递相关数据的方法。这在需要引用特定值或动态生成后续API请求的输入时尤其有用。使用 exports 字段,您可以增强API测试的灵活性和模块化,使它们更健壮且能适应不同场景。

什么是 JSONPath?

JSONPath 是一种强大的查询语言,旨在导航和从JSON文档中提取数据。它提供了一种简洁的语法,允许您指定到JSON结构中特定元素的路径,便于数据访问和操作。在 testkit 中,广泛使用JSONPath表达式来提取数据用于断言和导出。以下是一些示例来说明JSONPath的工作原理

  • $.user.name:此表达式从JSON文档的顶层对象中检索用户名称。
  • $.todos[0].task:此表达式访问todos数组中第一个元素的task属性。
  • $.todos[*].task.description:此表达式检索todos数组中所有任务的description属性。

JSONPath表达式的语法包括几个关键组件

组件 描述
括号表示法 通过在方括号内提供索引,访问数组中的元素([])。
通配符 匹配当前级别的任何元素,允许检索该级别的所有元素(*)。
递归下降 允许在JSON结构中任何深度搜索元素,包括嵌套对象和数组(..)。
过滤器 根据特定标准应用条件或过滤器以选择特定元素([?])。

通过使用JSONPath表达式,您可以在JSON结构中精确地定位所需数据。这些表达式在testkit中扮演着至关重要的角色,它有助于在测试过程中提取数据以进行断言和捕获导出。


[注意]

要了解更多关于JSONPaths的信息,请参阅官方文档

引用值和动态输入用于后续 API 请求

testkit中的exports字段不仅允许您从API响应中捕获值,而且还提供了一个强大的机制来引用这些值,并在后续的API请求中动态生成输入。

通过使用exports字段捕获相关数据,您可以将其存储为导出,并在测试场景的后续阶段轻松引用它。这种功能在您需要访问从响应中提取的特定值并在后续API请求中使用它们时尤其有用。

例如,假设您在第一阶段使用exports字段从一个API响应中检索一个ID

- title: Fetch User - GET
  GET: /users/1
  exports:
    userId: $.resp.body.id

为了在后续API请求中引用此userId导出,您可以使用$.stages[n].<VAL>语法

- title: Update User - PUT
  PUT: /users/$.stages[0].userId
  json:
    name: 'John Doe'

在上面的示例中,使用语法$.stages[0].userId访问了在第一阶段捕获的userIdtestkit理解它应该在执行期间用相应的值替换引用。

您还可以使用相对引用,如$.stages[-n],它引用当前阶段之前的第n个阶段的exports。示例

- title: deletes TODO items - DELETE
  DELETE: /todos/$.stages[-1].todoItem #-1 means one stage before me
  asserts:
    - string: $.resp.json.task
    - ok: $.resp.json.id == $.stages[-1].todoItem

通过引用之前阶段捕获的特定值,您可以在不同的API请求之间建立依赖关系,并确保在整个测试场景中无缝地流动数据。这种灵活性允许您构建更全面、更现实的测试,模拟复杂的用户交互或工作流程。

日期断言

要在testkit中进行日期断言,您需要提供日期字符串和日期格式,如下所示

- title: Get User Profile - GET
  GET: /user/jon_doe
  asserts:
    - date: $.resp.json.createdAt %Y-%m-%d %H:%M:%S %Z

在上面的示例中,我们首先提供一个JSONPath到日期,然后是日期的格式。

更多关于日期格式的内容

Testkit使用chrono crate的格式化标记来表示日期的不同组成部分。以下是一些常用的格式化标记

标记 含义 示例
%Y 带有世纪的年份的十进制数字。 2023
%m 作为零填充的十进制数字的月份。 07
%b%h 月份的缩写名称。 Jul
%B 月份的全称。 July
%d 月份中的日,作为零填充的十进制数字。 03
%A 星期的全称。 Monday
%a 星期的缩写名称。 Mon
%H 小时(00-23)。 14
%I 小时(01-12)。 03
%M 分钟(00-59)。 59
%S 秒(00-59)。 45
%p 12小时钟的AM/PM标识。 PM
%Z 时区偏移或名称。 UTC
示例日期及其格式

以下是一些示例日期及其正确的格式

日期字符串 格式
2023-07-26 %Y-%m-%d
2023-07-26 12:34:56 UTC %Y-%m-%d%H:%M:%S%Z
15 August, 1995, 03:45 PM UTC %d%B, %Y, %I:%M%p%Z
2022年12月5日 星期一 11:05:30 UTC %a, %d%b%Y%H:%M:%S%Z
2000年1月1日 - 00:00:00 UTC %B%d, %Y- %H:%M:%S%Z
1987/03/10 上午06:30 UTC %Y/%m/%d%I:%M%p%Z

在本表中,“日期字符串”列表示示例日期字符串,而“格式”列包含解析给定日期字符串的相应格式字符串。

使用环境变量

Testkit支持两种方式的环境变量(.env文件和CLI配置)。这些方法允许用户配置和自定义他们的测试脚本,同时不暴露敏感数据,使无缝切换不同环境和场景变得更容易。

配置环境变量

使用.env文件涉及到在测试脚本目录中创建一个名为.env的文本文件,并为每个环境变量定义KEY=VALUE对。在测试执行期间,testkit自动从.env文件中加载这些变量,如下所示

APIURL=https://api.example.com
EMAIL=[email protected]
PASSWORD=mysecretpassword
USERNAME=myusername
APIKEY=mysecretapikey

直接设置环境变量是通过命令行或测试环境完成的,如下所示

APIKEY=SECRETAPIKEY testkit test --file test.tk.yaml

利用环境变量

要在testkit中利用环境变量,可以使用以下语法:$.env.<VAL>,其中<VAL>表示您想要使用的特定环境变量的名称。这允许您轻松引用和结合使用这些环境变量的值,在测试脚本中,从而提供更大的灵活性和适应性,而不需要将敏感信息或配置细节硬编码。以下是一个示例

- title: Register
  POST: '$.env.APIURL/users'
  headers:
    Content-Type: application/json
    X-Requested-With: XMLHttpRequest
  json: '{"user":{"email":"$.env.EMAIL", "password":"$.env.PASSWORD", "username":"$.env.USERNAME"}}'
  asserts:
    - exists: $.resp.json.user
    - exists: $.resp.json.user.email
    - exists: $.resp.json.user.username
    - exists: $.resp.json.user.bio
    - exists: $.resp.json.user.image
    - exists: $.resp.json.user.token

在这个例子中,testkit向环境变量APIURL中指定的API URL执行POST请求。注册的用户信息来自环境变量EMAILPASSWORDUSERNAME,允许轻松自定义和重用测试脚本,跨不同环境。

贡献和帮助

要为此项目做出贡献或请求社区和我们的团队的帮助,请执行以下任何一项

许可协议

此存储库在MIT许可下发布。


依赖项

~24–38MB
~559K SLoC