shannonredeemed

CSV文件参数读取与【线程组】组件的线程数的关系

前言

  当你清早,经历了晨练、晨读、一个多小时的通勤、一顿匆匆的早饭、外加气喘吁吁的五层楼梯的攀爬,终于开始在工位坐定时,脑袋常常还没有进入工作状态——这个时候,我们需要的,往往是克服重重阻力,列出最为关键的待办清单,然后,打开工作界面,大脑在启动,运行速度还不能马上进入正轨……如果此时,我们的第一项工作,就是时隔多日,从头开始创建一个自动化脚本,那么,以下的问题,将很有可能发生——

踩坑之 —— 设计好了基本的脚本框架,并使用CSV作为案例参数,排除了CSV读取乱码和换行符的错误后,再次执行——竟然什么都没有发生

1、上配置

(1) 创建如下脚本结构 —— 各组件参数基本默认,预期结果,所有“是否执行”状态为1的参数行,都应该输出相应的testPoint变量值

image

image

 

image

 

 

image

  

2、 看执行情况 - 只输出了一个调试取样器,其他执行状态为1的参数行都没有输出,而且日志中,也没有报错。。。。

image

3、分析请教

  一顿重复执行,,,隐约中,我似乎觉察到了什么,,,修改了 【线程组】的线程数……问题竟然解决了!!!!!!再回过头看第一次执行的【调试取样器】,也确实看到,只有第一行的数据被读取了

image

 4、调试&解决

(1)增加【线程组】组件的循环次数 —— 想输出的参数行都输出了,可以解决问题!

image

 

image

 

(2)增加【线程组】组件的线程组数 —— 想输出的参数行都输出了,可以解决问题 too!

image

image

 

总结

  先请Deep Seek对Jmeter中的【CSV数据文件设置】组件的工作原理做一个梳理如下↓↓↓↓↓↓↓

 1 Shannon的问题:
 2     Jmeter 【CSV数据文件设置】组件的工作原理是什么?一行数据,就代表脚本从头到尾执行一次吗?
 3 
 4 Deep Seek的回答:
 5   JMeter 的 **CSV 数据文件设置** 组件是一个用于参数化的核心元件,其工作原理可以概括如下,并解答你的核心疑问:
 6 
 7 ### 核心工作原理
 8 
 9 1. **数据源:** 你指定一个 CSV 格式的文件(纯文本,数据项通常由分隔符如逗号分隔)。
10 2. **变量名:** 你定义变量名列表(如 `var1, var2, var3`),这些变量名将对应 CSV 文件中的每一列数据。
11 3. **读取机制:**
12 * JMeter 在测试运行时(线程启动时)打开文件(或根据配置在测试开始时打开)。
13 * 文件按**行**读取。
14 * 读取一行后,将该行的数据(按列分割)依次赋值给你定义的变量名。
15 * 下次需要读取数据时(例如,下一个需要该 CSV 数据的采样器执行前),JMeter 会读取下一行。
16 4. **共享模式:** 这是理解数据如何分配给线程的关键设置:
17 * **所有线程:** **默认且最常用。** 所有线程共享同一个文件指针。当一个线程读取一行后,文件指针移动到下一行,下一个读取的线程(可能是同一个线程的下一次循环,也可能是另一个线程)会读取下一行。这确保了在整个测试计划执行期间,数据行是按顺序被消耗的,通常用于模拟不同用户使用不同数据。
18 * **当前线程组:** 每个线程组有自己的文件指针副本。线程组内的线程共享该指针。不同线程组之间互不影响。
19 * **当前线程:** **每个线程拥有自己独立的文件指针副本。** 这意味着每个线程都会从 CSV 文件的第一行开始读取,并按照自己的迭代节奏读取后续行。通常用于每个线程需要独立遍历整个数据集(或部分数据集)的场景。
20 * **标识:** 需要配合 `__threadNum` 函数使用。每个线程会根据其编号(如线程1,线程2)去读取文件名中包含其编号的文件(例如 `data_${__threadNum}.csv`)。这实现了每个线程使用完全独立的数据文件。
21 
22 ### 解答核心疑问:一行数据就代表脚本从头到尾执行一次吗?
23 
24 **答案:不是的。**
25 
26 * **脚本执行次数由线程组设置决定:** 脚本(测试计划)的执行次数主要取决于:
27 1. **线程数:** 你定义的虚拟用户数。
28 2. **循环次数:** 每个线程执行的循环次数。
29 3. **调度器设置(如有):** 运行时长等。
30 * **总执行次数 ≈ 线程数 × 循环次数**
31 
32 * **CSV 数据行与脚本执行的关系:**
33 * **一行数据对应一次“数据消费点”的执行:** 每次 JMeter 需要从 CSV 文件中获取新数据时(通常发生在 HTTP 请求等采样器执行前,如果该采样器引用了 CSV 变量),它就会读取下一行(根据共享模式规则)。**这发生在一个脚本执行流程的某个具体步骤上。**
34 * **一次脚本循环可能消费多行数据:** 如果在一个线程的一次循环迭代中,有**多个**采样器或前置处理器等都配置了需要读取同一个 CSV 文件(或者同一个 CSV 变量被多次引用并触发了重新读取),那么**在这一次循环中就可能读取多行 CSV 数据**。例如:
35 * 循环迭代开始
36 * 登录请求:读取 CSV 行 N -> 使用 `username_N`, `password_N`
37 * 搜索请求:读取 CSV 行 N+1 -> 使用 `searchTerm_N+1`
38 * 退出请求:不需要新数据
39 * 循环迭代结束 -> 这次循环消费了 2 行 CSV 数据。
40 * **一次脚本循环可能消费零行或一行数据:** 如果一次循环中只有一个采样器需要 CSV 数据(或者需要数据的地方只引用了一次变量),那么这次循环通常只消费一行数据。
41 * **文件结束处理:** 当读取到文件末尾时,行为由配置决定:
42 * **Recycle on EOF? = True:** 文件指针重置到开头,重新从第一行读取。
43 * **Recycle on EOF? = False:** 停止读取(变量可能为空或保留最后的值,取决于配置)。
44 * **Stop thread on EOF? = True:** 如果 `Recycle=False`,则读取到 EOF 的线程会停止运行。
45 
46 ### 关键总结
47 
48 1. **CSV 数据文件按行读取,每次读取一行数据填充定义的变量。**
49 2. **脚本的整体执行次数由线程数和循环次数控制。**
50 3. **一行 CSV 数据的读取对应的是脚本执行流程中一个具体的“数据消费点”(通常是采样器执行时),而不是对应一次完整的脚本循环或整个测试计划。**
51 4. **一次脚本循环(一个线程的一次迭代)可能消费 0行、1行 或 多行 CSV 数据,这取决于在该次循环中有多少个地方触发了 CSV 文件的读取。**
52 5. **`共享模式` 决定了不同线程或线程组如何共享或隔离 CSV 文件的读取位置。**
53 
54 **简单比喻:**
55 
56 想象 CSV 文件是一个数据池(一叠卡片)。脚本执行就像一群人(线程)在按规则(共享模式)轮流从池子里抽卡片。
每次有人需要做一件具体的事情(比如发起一个请求),他就可能需要抽一张新卡片(读取一行数据)来获得做这件事所需的信息(变量值)。
一个人(一个线程)在一轮活动(一次循环)中可能需要做多件事(多个请求),所以可能需要抽多张卡片(读取多行数据)。
活动的总轮次(总执行次数)由人数(线程数)和每人轮次(循环次数)决定,而不是由卡片总数直接决定。
卡片(数据行)是在具体做事(执行采样器)时被消耗的。

 

  嗯……只能说,DS这篇原理分析,非常有料。。。。。可能需要反复阅读,才能消化吸收,但就驾驶汽车来说,我们常常不需要深入地理解轮子工作的原理……那么,就让我们简单谨记吧!—— 如果我们是在半梦游状态开始了一个全新的带【CSV数据文件设置】组件的Jmeter测试脚本,那么,当文件参数没有实现多行读取时,请一定关注一下 【线程组】组件的 线程数 或者 循环次数!~!~!~

   呛呛!~ 本篇博客就到这里啦!就像迷糊之中被雨水打了一个激灵,清醒之后,脚本就可以开足马力往前推进了!!!~ 一起来看看,前面还有什么怪兽、关卡在等着我们,冲啊~~~~

 

下期预告

  我们将继续关注CSV参数文件中的换行符号所引起的乱子,打眼一看,小妖怪的障眼法,可有两下子呢~~~

 

posted on 2025-08-31 19:17  Shannon_Zhang  阅读(13)  评论(0)    收藏  举报