Java JMeter 环境特定配置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22509990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JMeter environment specific configuration
提问by kan
I have several JMeter test plans which should be executed in different environments, say Dev, Test, UAT, Live. In each test plan I would like to have a simple way to specify which environment to use. Each environment has a lot of configuration such as hostname, port, ssl-cert, user name, password, account numbers and other test data.
我有几个 JMeter 测试计划,它们应该在不同的环境中执行,比如 Dev、Test、UAT、Live。在每个测试计划中,我都希望有一种简单的方法来指定要使用的环境。每个环境都有很多配置,比如主机名、端口、ssl-cert、用户名、密码、账号等测试数据。
One thing I'm trying to achieve is the ease of switching environments while using JMeter GUI or running scenarios from build scripts.
我试图实现的一件事是在使用 JMeter GUI 或从构建脚本运行场景时轻松切换环境。
One of my ideas is to use the "Include Controller" to include another jmx file which has list of User Defined Variables and other config elements. However, JMeter does not support variables in the included file name, so I cannot parametrise the scenario by an environment name. Include Controller supports JMeter parameter "includecontroller.prefix", but it is not very flexible, e.g. I cannot change it from JMeter GUI, I should change JMeter config files and restart it.
我的一个想法是使用“包含控制器”来包含另一个具有用户定义变量和其他配置元素列表的 jmx 文件。但是,JMeter 不支持包含的文件名中的变量,因此我无法通过环境名称对场景进行参数化。Include Controller 支持 JMeter 参数“includecontroller.prefix”,但它不是很灵活,例如我不能从 JMeter GUI 更改它,我应该更改 JMeter 配置文件并重新启动它。
I've tried to use Switch Controller, but no luck, it doesn't switch configuration elements, only samplers.
我试过使用 Switch Controller,但不走运,它不切换配置元素,只切换采样器。
What is the best practice to externalise environment specific configuration from test scenarios and share it between several scenarios?
从测试场景中外部化环境特定配置并在多个场景之间共享它的最佳实践是什么?
回答by Manish Sapariya
I have not used myself, but thisjmeter-pluing may help you. Here is snippet from documentation
我自己没用过,但是这个jmeter-pulling 可能对你有帮助。这是文档的片段
Parameterized Controller since 0.1.0
When your JMeter test plan tree becomes like a sequoia or a banyan,
you start feeling yourself like a monkey in a jungle, jumping from
branch to branch, trying to support this important test consistent.
You really need some way to have parameterized subroutines, to reuse
parts of test plan like regular programming language functions and
procedures.
JMeter have out-of-box Module controller, but it has no parameters
to pass to, so if you need to call repeating sequence of the same
action with different parameters, your reflection in a mirror starts
morphing into monkey. Parameterized Controller helps you stay human
and sane.
回答by Dmitri T
I would suggest to substitute all environment-specific variables or values with JMeter Properties. See following functions for reference:
我建议用 JMeter 属性替换所有特定于环境的变量或值。请参阅以下功能以供参考:
For example you can define a property called hostname
in either jmeter.propertiesfile or as JMeter command line argument as follows
例如,您可以定义hostname
在jmeter.properties文件或 JMeter 命令行参数中调用的属性,如下所示
jmeter -Jhostname=169.140.130.120 -n -t yourscript.jmx -l yourscriptresults.jtl
and refer to in inside your script as:
并在您的脚本中引用为:
${__P(hostname,)}
or${__property(hostname,,)}
${__P(hostname,)}
或者${__property(hostname,,)}
See Apache JMeter Properties Customization Guidefor more details.
有关更多详细信息,请参阅Apache JMeter 属性自定义指南。
回答by kc2001
I have the same problem. My current approach is to have several user defined variable (UDV) elements, e.g., DevVariables, TestVariables, etc. Each of these have the same variables defined (hostname, port, etc.). Then I manually disable those UDV elements that aren't in use.
我也有同样的问题。我目前的方法是拥有多个用户定义变量 (UDV) 元素,例如 DevVariables、TestVariables 等。每个元素都定义了相同的变量(主机名、端口等)。然后我手动禁用那些未使用的 UDV 元素。
Edit:
编辑:
The JMeter User Manualstates - "The User Defined Variables element lets you define an initial set of variables, just as in the Test Plan. Note that all the UDV elements in a test plan - no matter where they are - are processed at the start." I'm not sure what event constitutes the "start", but it makes it sound like you can't conditionally include UDVs, at least not via controllers.
在JMeter的用户手册状态- “用户定义的变量元素让你定义一组初始变量,就像在测试计划指出,所有的测试计划的UDV元素-无论他们在哪里-在开始处理.” 我不确定什么事件构成了“开始”,但这听起来好像你不能有条件地包含 UDV,至少不能通过控制器。
You may be able to have a single UDV per test plan, where you set the various variables (host, etc.). Maybe you can set each variable's value using an ugly JavaScript function that keys off of a passed-in property value.
每个测试计划可以有一个 UDV,您可以在其中设置各种变量(主机等)。也许您可以使用一个丑陋的 JavaScript 函数来设置每个变量的值,该函数从传入的属性值中删除。
You might try asking the question on the Apache JMeter User mailing list. There must be a way to do what you want.
您可以尝试在Apache JMeter 用户邮件列表上提问。必须有一种方法可以做你想做的事。
回答by kan
As the current solution I'm using JSR223 sampler with custom JavaScript code to set up variables from external properties-files. Something like that:
作为当前的解决方案,我使用带有自定义 JavaScript 代码的 JSR223 采样器来设置来自外部属性文件的变量。类似的东西:
var file = new java.io.File(args[0]);
var props = new java.util.Properties();
var is = new java.io.FileInputStream(file);
props.load(is);
is.close();
for(var it = props.entrySet().iterator(); it.hasNext();)
{
var entry = it.next();
vars.put(entry.getKey(), entry.getValue());
}
Now I just need to add this code as the very first sampler in a test plan and pass environment specific filepath as the sampler parameter args[0]
it will load variables from the file and put them as JMeter variables.
现在我只需要将此代码添加为测试计划中的第一个采样器,并将特定于环境args[0]
的文件路径作为采样器参数传递,它将从文件加载变量并将它们作为 JMeter 变量。
回答by Faflok
Like the Manish Sapariyamentioned, Parametrized Controlleris quite useful to prepare configuration for more than one environment. I used it in the previous place I worked and started the configuration now in new place. It is a bit of work at the beginning, but later it is easy in maintenance. There is a bit of tutorial in the link that is provided above, but it won't take in consideration that you want to run just one env at a time. I will describe it a bit below, maybe it will be useful.
So, slowly step by step:
就像Manish Sapariya提到的那样,参数化控制器对于为多个环境准备配置非常有用。我在以前工作的地方使用过它,现在在新地方开始配置。刚开始有点辛苦,后期维护起来就很方便了。上面提供的链接中有一些教程,但不会考虑您一次只想运行一个 env。我将在下面描述一下,也许它会有用。所以,一步一步慢慢来:
- First of all - you need two thread groups- one for environment profiles(no 1 on the first screenshot - Env Profiler) and one for your test cases, included test plans etc. (no 2 - API Requests). The latter has to be disabledas it is container that should not be executed straight from here (right click -> disable or Ctrl+T)
- Then you need your User Defined Variableselements (no 3) - I'm using three of them:
- first for defining which environment will be executed (environmentType var) and logins/passwords, tokens etc.
- second with IDs for items needed for tests
- third with IPs, ports, path prefixes and so on.
- 首先 - 您需要两个线程组-一个用于环境配置文件(第一个屏幕截图上没有 1 - Env Profiler),另一个用于您的测试用例,包括测试计划等(没有 2 - API 请求)。后者必须被禁用,因为它是不应直接从这里执行的容器(右键单击 -> 禁用或 Ctrl+T)
- 然后你需要你的用户定义变量元素(没有 3)——我使用了其中的三个:
- 首先用于定义将执行的环境(environmentType var)和登录名/密码、令牌等。
- 第二个带有测试所需项目的 ID
- 第三个是 IP、端口、路径前缀等。
The most important thing here is that I have them separated at this moment by prefixes in variable names, so in one UDV element I have variables like dev.serverIP, dev.serverPort, preprod.serverIPand so on (second screenshot) populated with values relevant for that environment. Additionally in one of this UDVs I have environmentType variable (mentioned earlier) with default value 'dev' (which you can change manually here or provide different value when launching through command line/CI or whatever)
这里最重要的事情是我现在用变量名称中的前缀将它们分开,所以在一个 UDV 元素中,我有变量,如dev.serverIP、dev.serverPort、preprod.serverIP等等(第二个屏幕截图)填充了值与该环境相关。此外,在其中一个 UDV 中,我有 environmentType 变量(前面提到过),默认值为“dev”(您可以在此处手动更改或在通过命令行/CI 或其他方式启动时提供不同的值)
Now in the Env Profiler I have If Controllers(no 4 on the first screenshot). For dev env I have (no 5 on the first screen):
"${environmentType}" == "dev"
现在在 Env Profiler 中,我有 If Controllers(第一个屏幕截图上没有 4)。对于开发环境,我有(第一个屏幕上没有 5):
"${environmentType}" == "dev"
For each env (if controller) you have to provide proper condition like this above.
对于每个环境(如果是控制器),您必须提供像上面这样的适当条件。
- Each IfController contains that "jp@gc - Parametrized Controller" mentioned before (that you can download as part of Extras Set hereby the way). In each Param Controller you assign to variables that you use in test plans variables specific for that environment, e.g. name: serverIP, value: ${dev.serverIP} for dev env (third screenshot)
- 每个 IfController 都包含前面提到的“jp@gc - 参数化控制器”(顺便说一下,您可以在此处下载它作为 Extras Set 的一部分)。在每个参数控制器中,您分配给您在测试计划中使用的特定于该环境的变量的变量,例如名称:serverIP,值:${dev.serverIP} 用于开发环境(第三个屏幕截图)
- And now the last thing - tests and plans you want to execute.
- In that disabled Thread Group (API Requests) you add Simple Controllersthat contains your tests or Include Controllersthat import some tests from other files.
- When you have those tests, for each one that you want to run in that particular environment you have to add Module cotroller inside Parametrized Controllerwith path to that test (screenshot below)
- 现在是最后一件事 - 您要执行的测试和计划。
- 在禁用的线程组(API 请求)中,您添加包含您的测试的简单控制器或从其他文件导入一些测试的包含控制器。
- 当您进行这些测试时,对于您想要在该特定环境中运行的每个测试,您必须在参数化控制器中添加模块控制器,并带有该测试的路径(下面的屏幕截图)
And that it is pretty much it. Now maintaining:
这几乎就是它。现在维护:
- to add new variable you have to add it in UDV with prefixes (dev.newVar, preprod.newVar) and fill the relevant values, then add proper entry in Parametrized controllers (those newVar = ${dev.newVar}) and that's it
- to add new test from other Test Plan - add Include controller with path to that file and add Module controller in each Paramterized controller directing them to that Include Controller
- to add new environment just copy the one you already have, change its If contr., Parametrized controller and fill values in UDVs The nice thing here is that if you want, lets say, dev env with all tests and the other with just some somke tests you can prepare a copy, change If controller to take some other value of env variable (like dev for all tests, devsmoke for smoke tests) and add or delete some of the module controllers in that new profile. Of course you can build it up a bit and you can ues different threads for different parts of the system for easier maintanance, just do not forget to disable those threads working as containers.
- 要添加新变量,您必须使用前缀(dev.newVar、preprod.newVar)将其添加到 UDV 中并填充相关值,然后在参数化控制器中添加适当的条目(那些 newVar = ${dev.newVar}),就是这样
- 从其他测试计划添加新测试 - 添加包含该文件的路径的包含控制器,并在每个参数化控制器中添加模块控制器,将它们定向到该包含控制器
- 要添加新环境,只需复制您已有的环境,更改其 If contr., Parametrized controller 并在 UDV 中填充值这里的好处是,如果您愿意,可以说,dev env 带有所有测试,而另一个仅带有一些 somke测试您可以准备一个副本,更改 If 控制器以获取 env 变量的一些其他值(如所有测试的 dev,烟雾测试的 devsmoke)并在该新配置文件中添加或删除一些模块控制器。当然,您可以稍微构建一下,您可以为系统的不同部分使用不同的线程以便于维护,只是不要忘记禁用这些线程作为容器工作。
I know it's a lot to do when you start, but it is not so bad later, when just adding some stuff - probably the easiest way to do it anyway.
我知道当你开始的时候有很多事情要做,但后来也没有那么糟糕,只是添加一些东西 - 无论如何可能是最简单的方法。
回答by Sven
I use a JSR223 sampler with Groovy to register new parameters. Make sure to put the JSR223 sampler in a Only Once Controller, so it is ran only once (per thread).
我使用带有 Groovy 的 JSR223 采样器来注册新参数。确保将 JSR223 采样器放在 Only Once Controller 中,因此它只运行一次(每个线程)。
I have in the test plan all variables registered for all environments like this:
我在测试计划中为所有环境注册了所有变量,如下所示:
TEST.user = 123
TEST.url = test.mysite.com
LOAD.user = 435
LOAD.url = load.mysite.com
Then I specify which environment I want to select with a command line parameter at startup like: -Denvironment=TEST
然后我在启动时使用命令行参数指定要选择的环境,例如: -Denvironment=TEST
My JSR223 script will add new variables to the test, without the TEST. prefix. In my scripts I just reference ${user}
我的 JSR223 脚本将在没有 TEST 的情况下向测试添加新变量。字首。在我的脚本中,我只是参考${user}
This is the script to use:
这是要使用的脚本:
JMeterVariables jmv = new JMeterVariables();
for (Map.Entry item : vars.entrySet()) {
if (item.getKey().startsWith(env)) {
String keyname = item.getKey().substring(env.length()+1);
String origval = vars.get(keyname);
if (origval==null || (origval.equals("") && !item.getValue().equals(""))) {
jmv.put(keyname, item.getValue());
}
}
}
if (!jmv.entrySet().isEmpty()) {
vars.putAll(jmv);
}
回答by Gubbi
I realize this question is old, but if you are using the GUI and running tests manually, one very simple approach is to have a User Defined Variables element per environment, and just have one of these enabled when running the test. But I still don't understand why jmeter does not support setting UDV:s conditionally.
我意识到这个问题很老,但是如果您使用 GUI 并手动运行测试,一种非常简单的方法是为每个环境设置一个用户定义的变量元素,并在运行测试时启用其中之一。但是我还是不明白为什么jmeter不支持有条件地设置UDV:s。