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

如何在Citrus框架多测试类中传递负载提取变量及使用TestContext?

嘿,我来帮你搞定Citrus框架里跨测试类共享auth-token的问题,顺便理清TestContext的用法~

解决Citrus框架跨类共享Auth-Token的问题

一、先搞懂TestContext的作用

每个Citrus测试类都会有自己的TestContext,它是当前测试实例的私有变量容器,用来存储提取的参数、测试数据、状态信息等。默认情况下这个上下文只能在当前测试类里用,要跨类共享token,就得把变量转移到全局可访问的存储里。

二、预测试步骤:把Token存入全局/共享容器

你的GetTokenIT已经能正确从响应头和 payload 里提取token了,现在要做的是把这些token从当前TestContext转移到全局可访问的地方,这里有两种常用方式:

方式1:用Citrus自带的全局变量

Citrus提供了全局变量存储池,所有测试类都能访问。修改你的GetTokenIT代码:

import com.consol.citrus.annotations.CitrusTest;
import com.consol.citrus.testng.TestNGCitrusTest;
import org.testng.annotations.BeforeSuite;

@BeforeSuite // 这个注解确保在所有测试套件启动前执行
public class GetTokenIT extends TestNGCitrusTest {

    @CitrusTest
    public void fetchAuthToken() {
        http()
            .client(HttpTqaClient)
            .receive()
            .response(HttpStatus.OK)
            .messageType(MessageType.JSON)
            .extractFromHeader("Authorization", "header_token")
            .extractFromPayload("$.id_token", "payload_token");

        // 把提取的token存入Citrus全局变量
        Citrus.citrusContext().getGlobalVariables().put("global_auth_header", context.getVariable("header_token"));
        Citrus.citrusContext().getGlobalVariables().put("global_id_token", context.getVariable("payload_token"));
    }
}

如果用JUnit 5,把@BeforeSuite换成@BeforeAll,并且把测试方法改成static即可。

方式2:自定义静态Token存储类

如果觉得全局变量不够直观,也可以自己写个简单的静态类来存token,更灵活:

// 自定义Token存储类,简单直接
public class TokenHolder {
    private static String authHeader;
    private static String idToken;

    public static void setAuthHeader(String token) {
        authHeader = token;
    }

    public static String getAuthHeader() {
        return authHeader;
    }

    public static void setIdToken(String token) {
        idToken = token;
    }

    public static String getIdToken() {
        return idToken;
    }
}

然后在GetTokenIT里通过AbstractTestAction把token存进去:

http()
    .client(HttpTqaClient)
    .receive()
    .response(HttpStatus.OK)
    .messageType(MessageType.JSON)
    .extractFromHeader("Authorization", "header_token")
    .extractFromPayload("$.id_token", "payload_token");

action(new AbstractTestAction() {
    @Override
    public void doExecute(TestContext context) {
        // 从当前TestContext取出token,存入自定义存储类
        TokenHolder.setAuthHeader(context.getVariable("header_token"));
        TokenHolder.setIdToken(context.getVariable("payload_token"));
    }
});

三、在其他TestIT类中使用共享的Token

现在不管用哪种方式,都能在其他测试类里轻松拿到token了:

方式1:用全局变量的场景

直接用Citrus的变量占位符${variableName}(会自动从全局变量取值),或者手动从全局变量池获取:

public class UserApiTestIT extends TestNGCitrusTest {

    @CitrusTest
    public void testGetUserInfo() {
        // 方式A:直接用Citrus占位符,自动匹配全局变量
        http()
            .client(HttpTqaClient)
            .send()
            .get("/api/user")
            .header("Authorization", "${global_auth_header}");

        // 方式B:手动从全局变量池获取
        String idToken = Citrus.citrusContext().getGlobalVariables().get("global_id_token");
        http()
            .client(HttpTqaClient)
            .send()
            .post("/api/verify")
            .payload("{\"token\": \"" + idToken + "\"}");
    }
}

方式2:用自定义TokenHolder的场景

直接调用静态方法获取token,代码可读性更高:

public class OrderApiTestIT extends TestNGCitrusTest {

    @CitrusTest
    public void testCreateOrder() {
        http()
            .client(HttpTqaClient)
            .send()
            .post("/api/orders")
            .header("Authorization", TokenHolder.getAuthHeader())
            .payload("{\"userId\": \"123\", \"token\": \"" + TokenHolder.getIdToken() + "\"}");
    }
}

四、注意事项

  • 执行顺序:一定要确保GetTokenIT在所有测试之前执行,TestNG的@BeforeSuite或者JUnit 5的@BeforeAll能帮你保证这一点。
  • 并行测试:如果开启了并行测试,全局变量可能会有线程安全问题,这时候可以用ThreadLocal改造TokenHolder,或者依赖Citrus的TestContext线程隔离特性。
  • 变量校验:提取token后最好加个非空校验,比如assertThat(context.getVariable("header_token")).isNotNull();,避免后续测试因为token为空失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:26:26