如果你希望 API 测试像自然语言一样易读,能够与代码一同存放在 Git 中,并且可以无缝运行在各种 CI 流水线里,那么 Karate 就是为这种需求打造的。它采用领域特定语言(DSL),让你通过 Given / When / Then 这样的步骤编写测试,而不是手写 Ja va 方法。本文将带你了解 Karate 是什么、feature 文件如何运作,并给出一个可直接上手的示例。
什么是 Karate
Karate 是一个基于 Ja va 的开源 API 自动化测试框架。它支持你直接在 .feature 文件中,使用源自行为驱动开发(BDD)的 Given/When/Then 结构,把每条测试用例写成清晰、可读的场景。与 Cucumber 这类工具相比,Karate 去掉了步骤定义(step-definition)这一层胶水代码,不需要再额外维护映射逻辑。更重要的是,它将 HTTP 请求、断言能力以及 JSON 处理内置到框架中,因此一套真正可执行的 API 自动化测试,通常无需编写任何 Ja va 代码。

Karate 的能力并不只局限于 API 测试。它的代码仓库还包含 mock、性能测试(通过 Gatling)以及 UI 自动化相关模块。不过本文会重点讲解 API 测试的核心功能,因为这通常是大多数团队接触 Karate 的第一步。
由于测试内容本质上是纯文本文件,所以非常适合版本控制。你可以在 Pull Request 中清楚看到断言、请求参数或场景逻辑的变更差异(diff),这让它与代码评审(code review)以及 Git 原生、代码优先的研发流程天然契合。
如果你对 Given/When/Then 这种写法还不熟悉,可以先阅读我们的行为驱动开发入门指南,了解它的起源、适用场景以及团队为什么喜欢这种方式。
工作原理:Feature 文件和 karate-config.js
Karate 测试从 feature 文件开始。每个文件都包含一个 Feature: 块,以及一个或多个 Scenario: 块。在每个场景中,你通过 Given 配置请求,通过 When 发起请求,再通过 Then 编写断言。
下面是 Karate 官方快速入门中展示的基础结构:
Feature: User APIScenario: List all usersGiven url 'https://jsonplaceholder.typicode.com'And path 'users'When method getThen status 200And match response == '#[10]'
这段代码可以按从上到下的顺序理解。url 用于设置基础 URL,path 用于拼接资源路径,method get 用于发送请求,status 200 用于校验 HTTP 状态码。最后一行表示断言响应是一个恰好包含 10 个元素的 JSON 数组。这里的 #[10] 是 Karate 的匹配标记,不是 Ja vaScript。想进一步了解这些标记,可以查看断言部分的说明。
这里使用的 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 userBackground:url baseUrlScenario: 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 在 API 自动化测试中的核心优势之一。最常用的关键字是 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 文件,因此你的测试数据可以根据团队习惯放在任何合适的位置统一维护。
在持续集成场景下,Karate 常见有两种运行方式。第一种是在 Ma ven 或 Gradle 项目中通过 JUnit 5 运行。你只需要添加 karate-junit5 依赖,并让 runner 指向对应的 feature 文件,那么 mvn test 就会像执行普通单元测试一样运行这些 API 自动化测试。这意味着现有 CI 流程通常不需要额外引入特殊工具。
第二种方式是使用独立的 jar 包,它不依赖构建工具。你可以从项目 releases 页面下载 karate.jar,然后直接运行 feature 文件。需要注意的是,该 jar 包通常要求较新的 Ja va 版本,因此建议查看发行说明(release notes)确认最低版本要求。
ja va -jar karate.jar src/test/ja va/features
你还可以通过标签过滤、并发执行以及指定输出目录来优化运行方式:
ja va -jar karate.jar --tags @smoke --threads 4 --output reports src/test/ja va/features
如果需要切换环境,可以通过系统属性传入环境变量,该值会注入到 karate-config.js 中的 karate.env:
ja va -jar karate.jar -Dkarate.env=qa src/test/ja va/features
Karate 每次运行结束后都会在输出目录生成 HTML 报告,因此在 CI 流水线产物中定位失败原因非常方便。想了解更完整的实践方式,可以继续阅读如何在 CI/CD 中实现 API 测试自动化。
优势与折中
Karate 的优势非常明确。首先,它的测试脚本读起来非常接近自然英语,大大降低了不熟悉 Ja va 的成员理解测试的门槛。其次,内置的 JSON 匹配能力,包括模糊匹配器和 each 校验,能显著减少样板断言代码。再者,所有测试都以文本形式保存在 Git 中,因此可以像源代码一样进行评审(review)和差异比对(diff)。此外,Karate 不仅适用于 HTTP API 测试,团队后续还可以基于同一工具继续扩展到 mock 或性能测试。
当然,它也存在一些取舍。Karate 运行在 JVM 上,因此需要安装 Ja va,并且在处理更复杂的工程化需求时,通常需要对 JVM 生态有基本了解。DSL 本身也需要一定学习成本;虽然语法读起来直观,但想写出稳定、可复用的匹配器和测试模式仍然需要经验积累。随着测试体系逐步变复杂,可复用逻辑、自定义辅助函数以及复杂初始化流程,往往还是会把你带回到 Ja vaScript 函数或 Ja va 互操作层面。另外,由于本质上仍属于“测试即代码”,团队中的非开发人员通常难以在没有帮助的情况下独立编写和维护它们。
这些并不能简单视为缺点,而更像是代码优先型 API 自动化测试框架的典型特征。关键问题在于,它是否适合你的团队协作方式和技术栈。
Karate 对比无代码方案 (Apifox)
Karate 是典型的代码驱动、Git 原生方案。你需要编写 feature 文件,将其提交到版本控制系统中,然后通过构建工具或 jar 包执行测试。这种模式非常适合希望把 API 测试与应用代码一起管理、并且熟悉 JVM 生态的工程团队。
Apifox 则采用可视化、无代码的方式实现类似目标。你可以在 UI 中搭建测试场景、串联多个请求,并通过点击配置而不是编写 DSL 的方式添加断言。由于 API 全生命周期能力——包括设计、调试、mock、文档和测试——都集中在同一个平台上,测试可以直接复用已有接口定义和数据模型。这对 QA 工程师以及不希望维护 Ja va 项目的产品或业务人员来说,门槛会更低。

-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 中通过可视化操作完成配置,同时依然支持接入自动化流水线。
如何选择
如果你的团队以专业开发者为主,熟悉 JVM,并且希望把测试作为代码与应用一起做版本控制,那么 Karate 会是很合适的选择。当工程师能够端到端掌控测试套件时,纯文本的 feature 文件和强大的 JSON 匹配能力会带来很高的效率。
如果测试编写者不仅包括开发人员,还包括 QA、产品或其他非技术角色,或者你希望把测试与现有 API 设计、文档流程打通,又或者你不想为了执行 API 校验而维护 Ja va 构建环境,那么像 Apifox 这样的无代码工具会更合适。你依然可以通过 CLI 在 CI 中获得自动化覆盖能力。
也有不少团队会组合使用两者:Karate 负责深度、代码优先的回归测试套件,可视化工具则负责更广范围、更快迭代、并且非开发人员也能参与维护的测试覆盖。如果你还在评估 API 自动化测试框架,可以继续阅读我们关于如何选择 API 自动化测试框架的系统概述。
FAQ
使用 Karate 需要懂 Ja va 吗? 不需要。编写基础的 API 自动化测试并不要求掌握 Ja va。Feature 文件使用的是 Gherkin DSL,而且 Karate 已经内置了 HTTP 请求和断言步骤。不过你仍然需要安装 Ja va 来运行测试;如果后续要编写自定义辅助函数或实现更复杂的复用,了解一些 Ja va 或 Ja vaScript 会更有帮助。
Karate 和 Cucumber 有什么区别? 两者都基于 Gherkin 的 Given/When/Then 语法。在 Cucumber 中,你需要为每个步骤编写对应的步骤定义代码。而在 Karate 中,常见的 API 测试步骤已经内置,因此对于标准 HTTP 接口测试,你通常不需要再维护额外的胶水代码。
Karate 可以在没有 Ma ven 或 Gradle 的情况下运行吗? 可以。你可以从项目的 Release 页面下载独立的 karate.jar,然后用 ja va -jar karate.jar 直接运行 feature 文件。它支持标签过滤、并行线程以及自定义输出目录,因此即使不依赖构建工具也能完成执行。
#string 或 #[10] 语法是什么意思? 这些是 Karate 提供的模糊匹配器(fuzzy matchers)。#string 表示断言某个字段是任意字符串,#number 表示该字段应为数字,而 #[10] 则表示断言响应为长度等于 10 的 JSON 数组。它们可以帮助你在不硬编码动态值的情况下完成结构校验。
无代码的 API 测试也能在 CI 中运行吗? 可以。像 Apifox 这样的可视化工具支持将已保存的测试场景通过 Apifox CLI 导出并执行。该 CLI 以无头(headless)方式运行,因此能够直接集成到任何支持 Node 的 CI 步骤中。也就是说,你可以在 UI 中完成测试编排,同时仍然具备自动化流水线执行能力。
开发必备:API 全流程管理神器 Apifox
在介绍完上面的 Karate API 测试内容后,我还想补充一个对开发团队同样很有价值的效率工具——Apifox。作为一个集 API 文档、调试、设计、测试、Mock、自动化测试于一体的平台,Apifox 已成为很多团队提升研发协作效率的重要选择。
如果你正在进行接口开发,不妨体验一下它简洁且友好的界面设计。它兼容 Postman 和 Swagger 数据格式,导入历史数据非常方便,即使是刚接触 API 工具的新手也能快速上手,点击这里即可注册使用。

值得一提的是,除了个人用户和常规团队协作场景,对于有高安全合规要求、或者需要在内网环境中协作的大型企业,Apifox 也提供了深度定制的私有化部署方案。
