0
点赞
收藏
分享

微信扫一扫

ThreadLocal在接口参数间传递中的使用


做过接口自动化测试的同学肯定都熟悉在全链路测试过程中,很多业务场景的完成并非由单一接口实现,而是由很多接口组成的一条链路实现。例如你在淘宝上购物场景。

ThreadLocal在接口参数间传递中的使用_依赖关系

不同于单接口测试,这种链路型的接口自动化测试,由于接口间有参数依赖关系,往往不能将链路中的接口入参固定写死,而是要依赖“上游”的响应中的某个字段值,因此需要提取出来动态地传递给下个接口,如下图。

ThreadLocal在接口参数间传递中的使用_依赖关系_02

解决链路间参数传递的问题可以简化为解决接口间的参数传递问题。当然我上图举例是比较简单的,下游对上游的依赖关系为1对1这种类型。实际业务场景中,更多的是多对一这种场景,即下游依赖上游的多个接口的返回结果。

试想一下,我们能否将整条链路可能使用到的字段集合作为一个池子,在上游接口的响应结果提取出key-value并扔到池子里。下游的接口request体模版化,以${xxx}表示需要替换的变量,利用模板引擎(例如Java的velocity)将${xxx}替换成“池子”中存在的value。实现的简图如下。

ThreadLocal在接口参数间传递中的使用_自动化_03

“ 池子” 的设计也可以使用ThreadLocal(线程变量),ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。

  • 因为每个 Thread 内有自己的实例副本,且该副本只能由当前 Thread 使用。
  • 既然每个 Thread 有自己的实例副本,且其它 Thread 不可访问,那就不存在多线程间共享的问题。

ThreadLocal 适用于每个线程需要自己独立的实例且该实例需要在多个方法中被使用,也即变量在线程间隔离而在方法或类间共享的场景

ThreadLocal实践

package cn.qa.threadLocal;

import java.util.HashMap;

public class ThreadLocaDemo {

private static ThreadLocal<HashMap> localMap = new ThreadLocal<HashMap>();

static void print(String str) {
//打印当前线程中本地内存中本地变量的值
System.out.println(str + " :" + localMap.get());
//清除本地内存中的本地变量
localMap.remove();
}

public static void main(String[] args) throws InterruptedException{

new Thread(new Runnable() {
@Override
public void run() {
HashMap<String, String> localA = new HashMap<>();
localA.put("localA", "localAValue");

ThreadLocaDemo.localMap.set(localA);
print("A");
//打印本地变量
System.out.println("after remove : " + localMap.get());

}
},"A").start();

Thread.sleep(1000);

new Thread(new Runnable() {
@Override
public void run() {
HashMap<String, String> localB = new HashMap<>();
localB.put("localB", "localBValue");

ThreadLocaDemo.localMap.set(localB);
print("B");
System.out.println("after remove : " + localMap.get());

}
},"B").start();
}
}

 A :{localA=localAValue}
after remove : null
B :{localB=localBValue}
after remove : null

可以在打印的结果中看到,设置的线程局部变量只在当前线程生效,这也非常适合接口间的传递原则。

举报

相关推荐

0 条评论