在使用多线程组模拟多用户并发测试时,每个用户所使用的数据源不一样,通过常规的添加配置文件-> CSV Data Set Config,文件共享属性只能设置所有现场、当前线程组,当前线程,前面两种是所有线程共同读取该文件,各线程读取先后顺序无法保证,导致将所有线程的源数据聚合到一个文件的想法泡汤;最后一直共享当前线程就更不行了,意思是每个线程都使用这个文件,线程之间各用各的,互不影响,每个线程都是从第一行数据开始依次读取,不同于前面两种的是每个线程读取的行数据是其他线程最后读取行号的下一行数据,无论那种方式都无法解决线程间的数据隔离。
解决方案
要做到线程间数据隔离,那么源数据就必须分开保存,要么保存在不同文件中,要么文件名相同路径不同
方法一:使用beanShell前置处理器读取文件内容
beanShell功能强大,几乎没有解决不了的问题,但代码繁琐,写的不好可能影响效率,大致思路是根据线程号查找文件或者根据不同用户的token查找文件,所有源文件要么按照线程号区分要么按照用户token区分,然后再beanShell里获取当前线程的线程号或者token,根据该值获取文件名,然后写个读取文件函数,注意每次读取后下次读取要读取下一行
方法二:使用CSVRead函数替代CSV Data Set Config配置文件:${__CSVRead(fileName,columNum)}
第一个参数:fileName表示要读取的文件名,假如10个线程,每个线程所有的源数据保存在src.csv文件中,10线程按照线程号区分源数据文件,则可将10个源数据文件依次命名为src1.csv/src2.csv...src10.csv,那么fileName传参就可以这么写:./src${__threadNum}.csv
第二个参数:columNum表示获取的列号,列号从0开始,若该值为next或者next()时表示跳转到下一行;所以每次使用完必须执行下${__CSVRead(./src${__threadNum}.csv,next)},否则会一直读取第一行的数据,该调用可以放在整个json的最后面也可以放在url后面,若一次请求存在多次使用该文件时,只要不放在中间就行,next执行的结果是一个空字符,所以放哪都行
CSV方法的缺陷:不支持自定义分隔符,若你的csv文件不是用逗号分割每列数据时,该方法会识别不到,因为源码中使用的是默认分割符,没有提供外部分隔符,要想支持自定义分隔符需要修改源码文件类CSVRead,增加一个参数,打包后替换当前lib/ext/目录的ApacheJMeter_functions.jar文件