1. 概述

本文将介绍Karate——一个基于Java的行为驱动开发(BDD)测试框架。它专为REST API测试设计,提供简洁高效的解决方案。

2. Karate与BDD

Karate构建于Cucumber之上,共享部分BDD核心概念,但关键区别在于

  • ✅ 测试用例完全使用Gherkin文件(.feature扩展名)描述
  • ❌ 无需编写Java代码实现测试逻辑

Gherkin文件结构示例:

Feature: 用户管理功能
  Scenario: 获取用户信息
    Given url 'https://api.example.com/users/1'
    When method GET
    Then status 200

核心关键字说明:

  • Feature:定义被测功能
  • Scenario:描述具体测试场景
  • Given/When/Then/And/But:构建测试步骤

3. Maven依赖和配置

3.1 添加依赖

<dependency>
    <groupId>com.intuit.karate</groupId>
    <artifactId>karate-junit4</artifactId>
    <version>1.3.1</version>
    <scope>test</scope>
</dependency>

3.2 资源目录配置

⚠️ 踩坑提醒:需在pom.xml添加以下配置,否则.feature文件无法被正确识别:

<build>
    <testResources>
        <testResource>
            <directory>src/test/java</directory>
            <excludes>
                <exclude>**/*.java</exclude>
            </excludes>
        </testResource>
    </testResources>        
</build>

配置目的

  • 将测试用例(.feature)与Java测试类放在同一目录
  • 分离普通测试资源与Gherkin文件

4. 创建测试

4.1 测试状态码

Scenario: 验证GET接口状态码
  Given url 'http://localhost:8097/user/get'
  When method GET
  Then status 200

关键点

  • method GET:发送HTTP GET请求
  • status 200:验证响应状态码
  • 支持所有HTTP状态码验证

4.2 测试响应

完整响应匹配

Scenario: 验证GET接口完整响应
  Given url 'http://localhost:8097/user/get'
  When method GET
  Then status 200
  And match $ == {id:"1234",name:"John Smith"}

部分字段验证

Scenario: 验证响应包含特定字段
  Given url 'http://localhost:8097/user/get'
  When method GET
  Then status 200
  And match $ contains {id:"1234"}

核心操作

  • match $$代表完整响应体
  • contains:验证响应包含指定字段(无需完全匹配)

4.3 使用标记验证响应值

当响应值不确定时,使用标记(marker)进行模糊匹配:

标记 说明
#null 值必须为null
#notnull 值不能为null
#boolean 布尔类型
#number 数字类型
#string 字符串类型
#array JSON数组
#object JSON对象
#uuid UUID格式
#regex STR 匹配正则表达式
#? EXPR 执行JavaScript表达式验证
#ignore 忽略字段验证

示例

Scenario: 使用标记验证响应
  Given url 'http://localhost:8097/user/get'
  When method GET
  Then status 200
  And match $ == {
    id: "#notnull",
    name: "#string",
    email: "#ignore"
  }

4.4 测试带请求体的POST接口

Scenario: 测试带请求体的POST接口
  Given url 'http://localhost:8097/user/create'
  And request { id: '1234', name: 'John Smith' }
  When method POST
  Then status 200
  And match $ contains {id:"#notnull"}

关键点

  • request:定义请求体(支持JSON/XML)
  • method POST:发送POST请求
  • 响应验证可复用前述所有技术

5. 运行测试

5.1 JUnit集成

创建JUnit测试类:

@RunWith(Karate.class)
public class KarateUnitTest {
    // 空实现即可,Karate自动扫描.feature文件
}

5.2 使用WireMock模拟服务

服务端模拟配置

private static WireMockServer wireMockServer = 
    new WireMockServer(WireMockConfiguration.options().port(8097));

@BeforeClass
public static void setUp() {
    wireMockServer.start();
    configureFor("localhost", 8097);
    
    // 模拟GET接口
    stubFor(get(urlEqualTo("/user/get"))
        .willReturn(aResponse()
            .withStatus(200)
            .withHeader("Content-Type", "application/json")
            .withBody("{ \"id\": \"1234\", \"name\": \"John Smith\" }")));
    
    // 模拟POST接口
    stubFor(post(urlEqualTo("/user/create"))
        .withHeader("content-type", equalTo("application/json"))
        .withRequestBody(containing("id"))
        .willReturn(aResponse()
            .withStatus(200)
            .withBody("{ \"id\": \"1234\", \"name\": \"John Smith\" }")));
}

@AfterClass
public static void tearDown() {
    wireMockServer.stop();
}

执行流程

  1. 启动WireMock服务器
  2. 注册模拟接口
  3. 运行Karate测试
  4. 关闭服务器

6. 总结

Karate框架的核心优势:

  • 零Java代码:纯Gherkin语法编写测试
  • 内置断言match操作支持多种验证方式
  • 标记系统:灵活处理动态响应值
  • 无缝集成:与JUnit/Maven/Gradle完美配合

适用场景

  • REST API契约测试
  • 微服务接口验证
  • 端到端流程测试

对于需要快速构建API测试套件的团队,Karate提供了简单粗暴的解决方案,特别适合敏捷开发环境。


原始标题:REST API Testing with Karate | Baeldung