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

Karate v0.95中Post请求未读取更新后CSV数据的问题排查

问题分析与解决方案:Karate CSV请求中Invoice Number不更新的问题

环境

  • Karate v0.95

问题场景

实现接收CSV文件的POST请求自动化测试,要求每次请求的CSV中invoice number字段保持唯一。

当前操作流程

  1. 在Feature文件的Background中,通过Java类读取CSV文件(01HappyPath-200.csv),更新invoice number为随机唯一值并覆盖保存原文件;
  2. 在Scenario中读取该CSV文件,随POST请求发送。

现象

本地CSV文件已成功更新为新的invoice number,但POST请求发送的仍是更新前的旧数据。

代码片段

Feature文件

Background:
    * call read("classpath:features/reusables/common/JSUtils.feature")
    * def invoiceNumber = getARandomNumberWithARange(1000000000)
    * print 'Random invoice number sent:',invoiceNumber
    * def javaclass = Java.type('javaReusables.manipulateCSV')
    * def csvInvNoUpd = new javaclass()
    * csvInvNoUpd.updateInvoiceNumber("src/test/resources/features/Invoice/requestBody/01HappyPath-200.csv", invoiceNumber)

Scenario: Verify invoice data is ingested
    Given url url
    And path 'testpath'
    And header Authorization = "Bearer "+sometoken
    And headers csvHeaders
    And def file = './requestBody/01HappyPath-200.csv'
    And request karate.readAsString(file)
    When method POST
    Then status 200

Java类

package javaReusables;

import com.opencsv.CSVReader;
import com.opencsv.CSVWriter;
import com.opencsv.exceptions.CsvException;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class manipulateCSV {

    //Takes CSV File and invoice number as parameters
    public void updateInvoiceNumber(String csvFile, String invoiceNumber) throws IOException, CsvException, InterruptedException {
        //Reads data from CSVFile and updates it
        CSVReader csvReader = new CSVReader((new FileReader(new File(csvFile))));
        List<String[]> allData = csvReader.readAll();
        String invoiceNo = allData.get(1)[6];
        System.out.println("Existing Invoice Number --> "+invoiceNo);
        allData.get(1)[6] = invoiceNumber;
        System.out.println("Updated Invoice Number --> "+invoiceNumber);

        //Writes updated data into CSVFile
        CSVWriter csvWriter = new CSVWriter(new FileWriter(new File(csvFile)));
        csvWriter.writeAll(allData);      
        csvWriter.close();
    }

}

问题原因

Karate在启动时会缓存classpath下的资源文件,你在Background中修改的是本地文件,但Scenario中调用karate.readAsString(file)时,实际读取的是Karate缓存的原始文件内容,而非更新后的本地文件。

另外,路径指向不一致也可能加剧问题:Java类使用绝对路径src/test/resources/...修改文件,而Feature中用相对路径./requestBody/...读取,Karate的资源加载机制会优先读取classpath缓存的版本。

解决方案

方案1:绕过Karate缓存,直接读取本地文件

修改Feature中的文件读取逻辑,用Java原生API读取本地文件,确保获取最新内容:

And def fileContent = new java.io.File('./requestBody/01HappyPath-200.csv').getText()
And request fileContent

方案2:内存中直接修改CSV内容(推荐)

完全避免文件IO操作,直接在内存中读取、修改CSV内容后发送请求,彻底规避缓存问题:

Background:
    * call read("classpath:features/reusables/common/JSUtils.feature")
    * def invoiceNumber = getARandomNumberWithARange(1000000000)
    * print 'Random invoice number sent:',invoiceNumber
    # 读取原始CSV内容
    * def csvContent = karate.readAsString('classpath:features/Invoice/requestBody/01HappyPath-200.csv')
    # 拆分CSV行,修改指定位置的invoice number
    * def rows = csvContent.split('\n')
    * def dataRow = rows[1].split(',')
    * dataRow[6] = invoiceNumber
    * rows[1] = dataRow.join(',')
    # 重新拼接为完整CSV
    * def updatedCsv = rows.join('\n')

Scenario: Verify invoice data is ingested
    Given url url
    And path 'testpath'
    And header Authorization = "Bearer "+sometoken
    And headers csvHeaders
    And request updatedCsv
    When method POST
    Then status 200

方案3:禁用Karate资源缓存(不推荐)

通过配置关闭资源缓存,但会影响整体测试性能,仅适合临时调试:
在karate-config.js中添加:

karate.configure('cache', false);

总结

优先选择方案2,内存中处理CSV内容无需修改本地文件,代码更简洁,也符合自动化测试的无状态最佳实践。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:20:20