你希望 API 测试读起来像普通的英语,能够与代码一起存放在 Git 中,并且可以在任何 CI 流水线中运行。Karate 正是为此而生。它使用了一种领域特定语言(DSL),让你能够以 Given / When / Then 步骤的形式编写测试,而不是编写 Java 方法。本指南将介绍 Karate 是什么、它的 feature 文件如何工作,并提供一个可运行的示例。
什么是 Karate
Karate 是一个基于 Java 的开源 API 自动测试框架。你可以在 .feature 文件中,使用源自行为驱动开发(BDD)的 Given/When/Then 结构,将每个测试描述为一个场景。与 Cucumber 等工具不同的是,你无需编写步骤定义(step-definition)的胶水代码。Karate 内置了 HTTP 步骤、断言和 JSON 处理功能,因此一个可运行的 API 测试完全不需要 Java 代码。

该项目不仅包含 API 测试。其代码仓库中还包含了用于 mock、性能测试(通过 Gatling)和 UI 自动化的模块。本指南将重点关注 API 测试核心功能,这也是大多数团队最先接触的部分。
由于测试是纯文本文件,因此它们非常易于进行版本控制。Pull Request 中的差异对比(diff)能清晰地展示出哪个断言发生了改变。这能很好地与代码评审(code review)以及基于 Git 原生、基于代码的工作流相结合。
如果你对 Given/When/Then 风格还不熟悉,可以阅读我们的行为驱动开发入门指南,了解其起源以及团队使用它的原因。
工作原理:Feature 文件和 karate-config.js
Karate 测试始于 feature 文件。每个文件包含一个 Feature: 块和一或多个 Scenario: 块。在场景内部,你使用 Given 设置请求,使用 When 发送请求,并使用 Then 进行断言。
以下是 Karate 官方快速入门中展示的结构:
Feature: User API
Scenario: List all users
Given url 'https://jsonplaceholder.typicode.com'
And path 'users'
When method get
Then status 200
And match response == '#[10]'
自上而下阅读该代码。url 设置了前置 URL。path 拼接了资源路径。method get 发送请求。status 200 检查 HTTP 状态码。最后一行断言响应是一个正好包含 10 个项的 JSON 数组。其中的 #[10] 是 Karate 标记,而不是 JavaScript。有关这些标记的更多信息,请参阅断言章节。
这里的 Gherkin 是标准的 Given/When/Then。如果你你想深入了解该语法本身,请参阅我们的 BDD 与 API 测试的 Gherkin 指南。
大多数项目都需要环境特定的值:例如开发环境的前置 URL、预发环境的 Token,以及生产环境的接口。Karate 通过一个名为 karate-config.js 的文件来处理这些问题。它在你的测试运行前执行一次,并返回一个每个场景都可以读取的配置 object。
function fn() { var env = karate.env || 'dev'; var config = { baseUrl: 'https://jsonplaceholder.typicode.com' }; if (env === 'qa') { config.baseUrl = 'https://qa.example.com'; } return config; }karate.env 来自于你在运行时传入的系统属性。无需修改任何 feature 文件即可切换环境。如此一来,在测试场景中你只需编写 Given url baseUrl,而无需硬编码地址。
示例测试场景
我们来编写一个包含请求 body 的用例。该测试场景将创建一个用户、检查状态并验证响应的结构。
gherkin Feature: Create user
Background:
url baseUrl
Scenario: Create a new user returns 201 Given path 'users' And request { name: 'Ada', job: 'engineer' } When method post Then status 201 And match response.name == 'Ada' And match response.id == '#string'有几点需要注意。Background: 模块在文件中的每个测试场景运行之前执行,因此你只需设置一次前置 URL。* 是一个通配符步骤;Karate 将 * 视为与 Given、When 或 Then 相同,这使你在编写初始化步骤时无需担心语法问题。request 关键字直接接收 JSON 载荷(payload),无需序列化器,也无需 POJO。而 #string 是一个模糊匹配器,用于断言 id 字段存在且为字符串,而无需将其固定为特定值。
断言与 JSON 匹配
断言是 Karate 的核心优势所在。其核心关键字是 match。它将实际值与预期值进行比较,并在出现任何不匹配时使测试失败。
精确匹配检查等价性:
gherkin And match response == { id: '#number', name: 'Ada', job: 'engineer' }#number、#string、#boolean 和 #uuid 等 Token 是模糊匹配器。它们只断言类型和是否存在,而不要求具体的字面值。当服务端返回自动生成的 ID 或时间戳时,这有助于保持测试的稳定性。
当你只关心部分字段时,可以使用 contains:
gherkin And match response contains { name: 'Ada' }只要 name 等于 Ada,该断言就会通过,即使响应中还包含其他十个字段。Karate 还支持 !contains、contains only、contains any 和 contains deep,以便对部分匹配进行更精细的控制。
你也可以验证数组。match response == '#[10]' 用于断言一个长度为 10 的数组。你可以使用 each 将数据模型应用到每个元素:
gherkin And match each response == { id: '#number', name: '#string' }仅需这一行代码,即可检查数组中的每个 object 是否都拥有数字类型的 id 和字符串类型的 name。在通用的测试框架中,这种结构验证通常需要编写循环和多个断言。如果你想全面了解如何校验响应,我们关于 API 断言的实用指南介绍了各种工具中的常用模式。
数据驱动测试与 CI
实际的测试套件通常需要针对许多不同的输入运行相同的逻辑。Karate 通过 Scenario Outline 和 Examples 表格来处理这种情况。尖括号中的占位符会替换为每一行中的对应数据。
Scenario Outline: Create users from a table
Given url baseUrl
And path 'users'
And request { name: '', job: '' }
When method post
Then status 201
And match response.name == ''
Examples:
| name | job |
| Ada | engineer |
| Grace | scientist |
| Alan | analyst |
这会运行该场景三次,每行运行一次。您还可以从外部文件读取行,而不是使用内联表,这样可以避免将大型数据集写入您的 feature 文件中:
Examples:
| read('classpath:test-data/users.json') |
Karate 以这种方式读取 JSON 和 CSV 文件,因此您的测试数据可以存放在团队偏好管理的任何位置。
对于持续集成,您有两条路径。在 Maven 或 Gradle 项目中,Karate 通过 JUnit 5 运行。您只需添加 karate-junit5 依赖项,并将 runner 指向您的 feature 文件,这样 mvn test 就会像执行任何其他单元测试一样执行它们。这意味着您现有的 CI 步骤不需要特殊的工具。
第二条路径是独立的 jar 包,它不需要构建工具。从项目的 releases 中下载 karate.jar 并直接运行 feature 文件。请注意,该 jar 包需要较新版本的 Java,因此请查看发行说明(release notes)以了解最低版本要求。
java -jar karate.jar src/test/java/features
您可以按标签进行过滤、并行运行并选择输出目录:
java -jar karate.jar --tags @smoke --threads 4 --output reports src/test/java/features
通过系统属性传递环境,该属性会流入到 karate-config.js 中的 karate.env:
java -jar karate.jar -Dkarate.env=qa src/test/java/features
Karate 在每次运行后都会向输出目录写入一份 HTML 报告,因此在流水线产物中很容易排查失败原因。有关更广泛的 CI 全景,请参阅如何在 CI/CD 中实现 API 测试自动化。
优势与折中
Karate 具有明显的优势。测试的阅读感非常接近纯英语,这为不熟悉 Java 的人降低了门槛。内置的 JSON 匹配(包括模糊匹配和 each)省去了大量的断言模板代码。所有内容都以文本文件的形式保存在 Git 中,因此测试可以像源码一样进行评审(review)和比对差异(diff)。此外,它涵盖的不止是 HTTP,团队以后可以在不更换工具的情况下添加 mock 或进行性能测试。
但折中也是显而易见的。Karate 运行在 JVM 上,因此您需要安装 Java,并且在处理基础之上的内容时,需要对 JVM 生态系统有一定的了解。DSL 本身也需要学习;虽然语法读起来很容易,但编写正确的匹配器和重用模式需要练习。可重用的逻辑、自定义助手和复杂的设置往往会把您拉回到 JavaScript 函数或 Java 互操作上。而且因为测试即代码,团队中的非开发人员通常在没有帮助的情况下无法编写或编辑它们。
这些并不是什么缺点,而是“代码优先”框架的典型特征。关键在于这是否符合您团队的工作方式。
Karate 对比无代码方案 (Apifox)
Karate 是基于代码且 Git 原生的。你需要编写 feature 文件,提交它们,然后通过构建工具或 jar 包运行它们。这非常适合那些希望将测试与应用程序一起放入版本控制,并且熟悉 JVM 的工程师。
Apifox 则通过可视化的无代码方式来实现相同的目标。你可以在 UI 中构建测试场景、串联请求,并通过点击而不是编写 DSL 来添加断言。由于整个 API 生命周期(设计、调试、mock、文档)都集中在一个地方,测试可以复用你已经定义的接口和数据模型。这降低了 QA 工程师和不想管理 Java 项目的产品人员的门槛。

这种可视化套件并不局限于 UI 界面。Apifox 支持在 CI 中通过 Apifox CLI 以无头模式运行它们,因此无代码套件仍然可以无缝接入自动化流水线。你可以使用 Node 来安装它:
npm install -g apifox-cli
然后通过 ID 触发已保存的测试场景或套件,指定环境并选择报告格式:
apifox run --access-token "$APIFOX_ACCESS_TOKEN" -t <scenarioOrSuiteId> -e <environmentId> -r cli,html,junit
-t 参数指向测试场景、目录或套件;-e 用于选择环境;-r 用于指定一个或多个报告器(cli、html、json、junit)。对于数据驱动的运行,-d(或 --iteration-data)可以接收数据文件路径或测试数据 ID。该 CLI 是无头的,可以在任何支持运行 Node 的 CI 步骤中执行。它运行的是你保存的 Apifox 测试场景,而不是一个交互式的请求发送器或负载生成器。有关完整指南,请参阅 Apifox CLI 中的 CI/CD,以及与其他运行器的对比:Apifox CLI vs Newman。
这两种方法都能生成在 CI 中无头运行的自动化 API 测试。两者的区别主要在于编写风格:Karate 需要你在 Git 中编写 DSL;而 Apifox 则让你在 UI 中进行点击操作,同时也能导出到流水线中。
如何选择
如果你的团队以 proto 开发者为主、熟悉 JVM,并且希望将测试作为代码与应用程序一起进行版本控制,请选择 Karate。当工程师端到端地掌控测试套件时,纯文本的 feature 文件和内置的 JSON 匹配功能将发挥巨大的威力。
如果测试编写人员包括 QA 和产品人员,或者你希望将测试与现有的设计和文档工作流相结合,又或者你不想为了运行 API 检查而维护 Java 构建,请选择像 Apifox 这样的无代码工具。你仍然可以通过 CLI 获得 CI 覆盖率。
一些团队会两者结合使用:Karate 用于深度、以代码为核心的回归测试套件,而可视化工具则用于非开发人员也可以扩展的广泛、快速的测试覆盖。如果你仍在权衡选择,我们关于如何选择 API 自动化测试框架的概述阐述了决策标准。
FAQ
使用 Karate 需要懂 Java 吗? 不需要,编写基础的 API 测试不需要懂 Java。Feature 文件使用 Gherkin DSL,且 Karate 内置了 HTTP 和断言步骤。你需要安装 Java 来运行测试,而如果你需要自定义辅助函数或进行复杂的复用,了解一些 Java 或 JavaScript 会很有帮助。
Karate 和 Cucumber 有什么区别? 两者都使用 Gherkin 的 Given/When/Then 语法。在 Cucumber 中,你需要编写步骤定义代码来支持每个步骤的执行。而 Karate 已经为你提供了 API 测试步骤,因此对于标准的 HTTP 测试,你无需维护任何粘合代码。
Karate 可以在没有 Maven 或 Gradle 的情况下运行吗? 可以。从项目的 Release 页面下载独立的 karate.jar,然后使用 java -jar karate.jar <path> 运行 feature 文件。它支持标签、并行线程以及自定义输出目录,无需任何构建工具。
#string 或 #[10] 语法是什么意思? 这些是 Karate 的模糊匹配器(fuzzy matchers)。#string 断言某个字段是任意值的字符串,#number 断言其为数字,而 #[10] 则断言其为一个长度为 10 的 JSON 数组。它们允许你在不硬编码生成值的情况下校验响应的结构。
无代码的 API 测试还可以在 CI 中运行吗? 可以。像 Apifox 这样的可视化工具可以将保存的测试场景导出到 Apifox CLI,它是无头(headless)的,可以在任何运行 Node 的 CI 步骤中执行。因此,你可以在 UI 中编写测试,但仍然可以进行自动化的流水线运行。
开发必备:API 全流程管理神器 Apifox
介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档、调试、设计、测试、Mock、自动化测试于一体的工具,Apifox 是目前提升研发效率的首选。
如果你正在开发项目,不妨试试其极其友好的界面设计,它完全兼容 Postman 和 Swagger 数据格式,导入数据非常方便,,即使是新手也能很快上手,点击这里即可注册使用。

值得一提的是,除了个人和常规团队使用,针对有高安全合规要求、或需要在内网环境协作的企业,Apifox 还提供了深度定制的私有化部署方案。
获取专属报价与部署方案
详细的私有化部署系统架构与安全白皮书
针对您公司规模的专属报价单
免费的 1v1 专属产品演示 (Demo) 机会