以编程方式执行 Gatling 测试
Programmatically execute Gatling tests
我想使用 Cucumber JVM 之类的东西来驱动为 Gatling 编写的性能测试。
理想情况下,Cucumber 功能会以某种方式动态构建场景 - 可能会重用类似于 "Advanced Tutorial" 中描述的方法的预定义链对象,例如
val scn = scenario("Scenario Name").exec(Search.search("foo"), Browse.browse, Edit.edit("foo", "bar")
我查看了 Maven 插件如何执行脚本,我也看到了使用 App 特征的提及,但我找不到关于后者的任何文档,令我震惊的是其他人会有以前想这样做...
任何人(加特林新手)都可以指出一些文档或示例代码的方向来实现这一点吗?
编辑 20150515
所以再解释一下:
我创建了一个特征,它旨在建立一系列我认为由 Cucumber 步骤触发的 ChainBuilder:
trait GatlingDsl extends ScalaDsl with EN {
private val gatlingActions = new ArrayBuffer[GatlingBehaviour]
def withGatling(action: GatlingBehaviour): Unit = {
gatlingActions += action
}
}
GatlingBehaviour 类似于:
object Google {
class Home extends GatlingBehaviour {
def execute: ChainBuilder =
exec(http("Google Home")
.get("/")
)
}
class Search extends GatlingBehaviour {...}
class FindResult extends GatlingBehaviour {...}
}
在 StepDef 中 class:
class GoogleStepDefinitions extends GatlingDsl {
Given( """^the Google search page is displayed$""") { () =>
println("Loading www.google.com")
withGatling(Home())
}
When( """^I search for the term "(.*)"$""") { (searchTerm: String) =>
println("Searching for '" + searchTerm + "'...")
withGatling(Search(searchTerm))
}
Then( """^"(.*)" appears in the search results$""") { (expectedResult: String) =>
println("Found " + expectedResult)
withGatling(FindResult(expectedResult))
}
}
想法是我可以通过类似以下的方式执行整个操作序列:
val scn = Scenario(cucumberScenario).exec(gatlingActions)
setup(scn.inject(atOnceUsers(1)).protocols(httpConf))
然后检查报告或在测试失败时捕获异常,例如响应时间太长。
似乎无论我如何使用'exec'方法,它都试图立即执行它,而不是等待场景。
我也不知道这是否是最好的方法,我们想为我们的 Gatling 测试构建一些可重用的块,这些块可以通过 Cucumber 的 Given/When/Then 样式构建。是否有更好的或已经存在的方法?
遗憾的是,目前无法让 Gatling 直接启动 Simulation 实例。
并不是说它在技术上不可行,而是您只是第一个尝试这样做的人。
目前,Gatling 通常负责编译,只能通过 class 的名称来加载,而不是实例本身。
您可以从分叉 io.gatling.app.Gatling
和 io.gatling.core.runner.Runner
开始,然后提供 PR 来支持这种新行为。前者是主要入口点,后者可以实例化和 运行 模拟。
我最近运行遇到了类似的情况,不想fork gatling。虽然这解决了我眼前的问题,但它只是部分解决了您正在尝试做的事情,但希望其他人会发现这很有用。
还有一个选择。 Gatling 是用 Java 和 Scala 编写的,因此您可以直接调用 Gatling.main 并将您需要的参数传递给 运行 您想要的 Gatling Simulation。问题是, main 显式调用 System.exit 因此您还必须使用自定义安全管理器来防止它实际退出。
你需要知道两件事:
- 您想要 运行 的模拟 class(带有完整包)
示例:com.package.your.Simulation1
- 编译二进制文件的路径。
运行 模拟的代码:
protected void fire(String gatlingGun, String binaries){
SecurityManager sm = System.getSecurityManager();
System.setSecurityManager(new GatlingSecurityManager());
String[] args = {"--simulation", gatlingGun,
"--results-folder", "gatling-results",
"--binaries-folder", binaries};
try {
io.gatling.app.Gatling.main(args);
}catch(SecurityException se){
LOG.debug("gatling test finished.");
}
System.setSecurityManager(sm);
}
我使用的简单安全管理器:
public class GatlingSecurityManager extends SecurityManager {
@Override
public void checkExit(int status){
throw new SecurityException("Tried to exit.");
}
@Override
public void checkPermission(Permission perm) {
return;
}
}
问题是在 运行 之后从模拟中获取您想要的信息。
我想使用 Cucumber JVM 之类的东西来驱动为 Gatling 编写的性能测试。
理想情况下,Cucumber 功能会以某种方式动态构建场景 - 可能会重用类似于 "Advanced Tutorial" 中描述的方法的预定义链对象,例如
val scn = scenario("Scenario Name").exec(Search.search("foo"), Browse.browse, Edit.edit("foo", "bar")
我查看了 Maven 插件如何执行脚本,我也看到了使用 App 特征的提及,但我找不到关于后者的任何文档,令我震惊的是其他人会有以前想这样做...
任何人(加特林新手)都可以指出一些文档或示例代码的方向来实现这一点吗?
编辑 20150515
所以再解释一下:
我创建了一个特征,它旨在建立一系列我认为由 Cucumber 步骤触发的 ChainBuilder:
trait GatlingDsl extends ScalaDsl with EN {
private val gatlingActions = new ArrayBuffer[GatlingBehaviour]
def withGatling(action: GatlingBehaviour): Unit = {
gatlingActions += action
}
}
GatlingBehaviour 类似于:
object Google {
class Home extends GatlingBehaviour {
def execute: ChainBuilder =
exec(http("Google Home")
.get("/")
)
}
class Search extends GatlingBehaviour {...}
class FindResult extends GatlingBehaviour {...}
}
在 StepDef 中 class:
class GoogleStepDefinitions extends GatlingDsl {
Given( """^the Google search page is displayed$""") { () =>
println("Loading www.google.com")
withGatling(Home())
}
When( """^I search for the term "(.*)"$""") { (searchTerm: String) =>
println("Searching for '" + searchTerm + "'...")
withGatling(Search(searchTerm))
}
Then( """^"(.*)" appears in the search results$""") { (expectedResult: String) =>
println("Found " + expectedResult)
withGatling(FindResult(expectedResult))
}
}
想法是我可以通过类似以下的方式执行整个操作序列:
val scn = Scenario(cucumberScenario).exec(gatlingActions)
setup(scn.inject(atOnceUsers(1)).protocols(httpConf))
然后检查报告或在测试失败时捕获异常,例如响应时间太长。
似乎无论我如何使用'exec'方法,它都试图立即执行它,而不是等待场景。
我也不知道这是否是最好的方法,我们想为我们的 Gatling 测试构建一些可重用的块,这些块可以通过 Cucumber 的 Given/When/Then 样式构建。是否有更好的或已经存在的方法?
遗憾的是,目前无法让 Gatling 直接启动 Simulation 实例。
并不是说它在技术上不可行,而是您只是第一个尝试这样做的人。 目前,Gatling 通常负责编译,只能通过 class 的名称来加载,而不是实例本身。
您可以从分叉 io.gatling.app.Gatling
和 io.gatling.core.runner.Runner
开始,然后提供 PR 来支持这种新行为。前者是主要入口点,后者可以实例化和 运行 模拟。
我最近运行遇到了类似的情况,不想fork gatling。虽然这解决了我眼前的问题,但它只是部分解决了您正在尝试做的事情,但希望其他人会发现这很有用。
还有一个选择。 Gatling 是用 Java 和 Scala 编写的,因此您可以直接调用 Gatling.main 并将您需要的参数传递给 运行 您想要的 Gatling Simulation。问题是, main 显式调用 System.exit 因此您还必须使用自定义安全管理器来防止它实际退出。 你需要知道两件事:
- 您想要 运行 的模拟 class(带有完整包) 示例:com.package.your.Simulation1
- 编译二进制文件的路径。
运行 模拟的代码:
protected void fire(String gatlingGun, String binaries){
SecurityManager sm = System.getSecurityManager();
System.setSecurityManager(new GatlingSecurityManager());
String[] args = {"--simulation", gatlingGun,
"--results-folder", "gatling-results",
"--binaries-folder", binaries};
try {
io.gatling.app.Gatling.main(args);
}catch(SecurityException se){
LOG.debug("gatling test finished.");
}
System.setSecurityManager(sm);
}
我使用的简单安全管理器:
public class GatlingSecurityManager extends SecurityManager {
@Override
public void checkExit(int status){
throw new SecurityException("Tried to exit.");
}
@Override
public void checkPermission(Permission perm) {
return;
}
}
问题是在 运行 之后从模拟中获取您想要的信息。