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

Karate MasterRunner运行报PolyglotException单场景执行正常

问题现象

在使用Karate 1.1.0版本开展自动化测试时,通过MasterTestRunner主运行器执行测试(配置项:并行度为1、输出Cucumber JSON与JUnit XML报告、绑定ExtentReport钩子、筛选@test标签用例),调用utils类静态方法returnIds时抛出异常。

异常堆栈

org.graalvm.polyglot.PolyglotException: java.lang.AssertionError
com.oracle.truffle.polyglot.PolyglotList$Cache.lookup(PolyglotList.java:180)
com.oracle.truffle.polyglot.PolyglotList.<init>(PolyglotList.java:73)
com.oracle.truffle.polyglot.PolyglotList.create(PolyglotList.java:96)
com.oracle.truffle.polyglot.PolyglotHostAccess.toList(PolyglotHostAccess.java:107)
com.oracle.truffle.host.HostToTypeNode.asJavaObject(HostToTypeNode.java:384)
com.oracle.truffle.host.HostToTypeNode.convertImpl(HostToTypeNode.java:194)
com.oracle.truffle.host.HostToTypeNode.doCached(HostToTypeNode.java:118)

关联代码与配置

主运行器代码

package tests;

import com.intuit.karate.Results;
import com.intuit.karate.Runner;
import net.masterthought.cucumber.Configuration;
import net.masterthought.cucumber.ReportBuilder;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Test;
import reporting.ExtentReport;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MasterTestRunner {

    // this will run all *.feature files  
    /*@Karate.Test
    Karate testAll() {
        return Karate.run().relativeTo(getClass());
    }*/

    //Karate Parallel Runner
    @Test
    public void testParallel() {
        final Results results = Runner.path("classpath:tests/features").hook(new ExtentReport()).tags("@test")
                .outputCucumberJson(true).outputJunitXml(true).parallel(1);
        assertEquals(0, results.getFailCount(), results.getErrorMessages());
    }

    //Boiler Plate for Cucumber report generation
    public static void generateReport(final String karateOutputPath) {
        final Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[]{"json"}, true);
        final ArrayList<String> jsonPaths = new ArrayList<>(jsonFiles.size());
        jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
        final Configuration config = new Configuration(new File("target"), "Karate test");
        System.out.println("config report " + config.getBuildNumber());
        final ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
        reportBuilder.generateReports();
    }
}

问题特征

  • 异常仅在通过主运行器执行时触发,单独运行对应feature文件时用例可正常执行、无报错。

测试Feature文件内容

Feature: karate testing

  @test
  Scenario: Karate test case
    * def acts = [  {  "label": "BUSINESS","name": "David","id": "u374892","type": "DIVISION"},{"label": "Division","name":"MILLER","id": "u236478","type": "BUSINESS"}]
    * def data1 = [{"UserName": "ABENANTE","UserID": "u109238","Role": "BUSINESS"},{"UserName": "Louis","UserID": "u784784","Role": "DIVISION"}]
    * def desk = utils.returnIds(data1, 2, acts, "DESK")
    * print desk

Java工具方法签名

public static List<Map<String, Object>> returnIds(List<Map<String, Object>> listOfAllIds, int numberOfIds, List<Map<String, Object>> listOfIds, String role)

Maven依赖配置

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    <maven.compiler.version>3.6.0</maven.compiler.version>
    <karate.version>1.1.0</karate.version>
</properties>

<dependencies>
    <!-- For Karate Begin -->
    <dependency>
        <groupId>com.intuit.karate</groupId>
        <artifactId>karate-junit5</artifactId>
        <version>${karate.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.intuit.karate</groupId>
        <artifactId>karate-gatling</artifactId>
        <version>${karate.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>

排查思路与解决方案

  • 根因定位:该问题是Karate 1.1.0版本内置GraalVM引擎的已知bug。单独运行Feature时走单例非并行执行上下文,JS数组转Java List的类型转换缓存可正常命中;通过parallel()方法启动运行器时(哪怕并行度设置为1),会走隔离上下文执行逻辑,GraalVM的PolyglotList缓存校验逻辑存在缺陷,触发AssertionError。
  • 优先修复方案:直接升级Karate版本到1.2.0及以上稳定版本,官方已在后续版本修复该GraalVM类型转换缓存异常问题。
  • 临时规避方案(无法升级版本时可选用):
    • 入参提前转换:调用Java静态方法前,手动将Feature中定义的JS数组转为原生Java List,绕开GraalVM自动类型转换逻辑,示例代码:
      * def ArrayList = Java.type('java.util.ArrayList')
      * def data1 = ArrayList.from(data1)
      * def acts = ArrayList.from(acts)
      * def desk = utils.returnIds(data1, 2, acts, "DESK")
      
    • 调整方法入参类型:修改Java工具方法的入参定义,将强类型List<Map<String, Object>>改为通用Object类型,在方法内部自行完成类型判断与转换,避开GraalVM自动泛型类型匹配转换逻辑。
    • 钩子兼容性校验:临时移除绑定的ExtentReport自定义钩子后重试,部分自定义实现的Karate钩子会错误修改GraalVM宿主访问配置,触发类型转换异常。
  • 依赖冲突排查:执行mvn dependency:tree查看依赖树,排查是否存在手动引入的、与Karate内置版本不一致的GraalVM、Truffle相关依赖,存在冲突时直接排除多余依赖即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:06:24