You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Karate中使用Scenario Outline读取两个.csv文件并实现请求与响应文件的匹配校验?

Yes, You Absolutely Can Do This in Karate!

Karate was built specifically for data-driven testing scenarios like this—using CSV files to generate request payloads and validate API responses against expected CSV data is not only possible but one of its core strengths. Let’s break down the process with concrete, actionable examples.

Step 1: Set Up Your CSV Files

First, let’s define sample CSV structures to work with. Let’s say you have:

request-data.csv (for generating payloads):

user_id,full_name,email
1,Alice Smith,alice@test.com
2,Bob Johnson,bob@test.com

expected-responses.csv (for validation):

user_id,status_code,response_message
1,200,"User registered successfully"
2,200,"User registered successfully"

Step 2: Write the Karate Feature File

Here’s a complete feature that reads both CSVs, sends requests for each row, and validates responses against the expected data. We’ll cover two common approaches:

Approach 1: Using Scenario Outline (Clean, Readable)

This uses Karate’s scenario outline to loop through CSV rows automatically:

Feature: Validate API with CSV Input/Output

  Background:
    * url 'https://your-api-base-url.com/register'
    # Load both CSV files into Karate variables
    * def requestRows = read('request-data.csv')
    * def expectedRows = read('expected-responses.csv')

  Scenario Outline: Test each user registration request
    Given request { user_id: <user_id>, full_name: '<full_name>', email: '<email>' }
    When method POST
    Then status <expected_status>
    And match response.message == '<expected_message>'
    # Optional: Validate the returned user ID matches the request
    And match response.user_id == <user_id>

    Examples:
      | user_id | full_name     | email           | expected_status | expected_message               |
      | karate.forEach(requestRows, expectedRows, (req, exp) => ({ 
          user_id: req.user_id, 
          full_name: req.full_name, 
          email: req.email, 
          expected_status: exp.status_code, 
          expected_message: exp.response_message 
        })) |

Approach 2: Using a Direct Loop (Flexible for Complex Logic)

If you need more control (like handling dynamic data or custom mappings), use a karate.forEach loop:

Scenario: Iterate through CSV data and validate responses
    * url 'https://your-api-base-url.com/register'
    * def requestRows = read('request-data.csv')
    * def expectedRows = read('expected-responses.csv')

    # Create a lookup map for expected responses (useful if rows aren't in order)
    * def expectedLookup = karate.map(expectedRows, (exp) => ({ key: exp.user_id, value: exp }))

    * karate.forEach(requestRows, (req) => {
        Given request req
        When method POST
        Then status expectedLookup[req.user_id].status_code
        And match response.message == expectedLookup[req.user_id].response_message
        # Add custom validation here (e.g., check timestamp format)
        And match response.timestamp =~ '#regex \\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}'
      })

Key Tips for Smooth Implementation

  • Nested Payloads: If your API expects nested JSON, use dot notation in your CSV headers (e.g., user.full_name, contact.email)—Karate will auto-convert this into nested objects.
  • Dynamic Values: For response fields that change (like timestamps or generated IDs), use Karate’s fuzzy matching:
    And match response.generated_id != null
    And match response.created_at =~ '#regex \\d{4}-\\d{2}-\\d{2}'
    
  • Large Datasets: Karate handles large CSV files efficiently, but if you need to filter rows, use karate.filter before looping:
    * def filteredRequests = karate.filter(requestRows, (req) => req.user_id > 1)
    

内容的提问来源于stack exchange,提问作者SujitLearner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 07:22:39