前言:刚开始用 ngrinder,发现网上混合场景压测的例子太少了,自己去查了很多资料,也去 github 上看介绍,总结出了以下两种方式,现在还有一个问题没有解决。(jython 可以通过导入 py 文件的方式,将多个单接口的测试脚本,导入到一个脚本里进行压测。但是 groovy 我没找到相同的办法,将多个单接口的测试脚本,导入到一个脚本里进行压测,现在只能将多个 test 方法写到一个文件里,显得比较臃肿,希望有此解决办法的大神,留言评论)
一、控制主循环里的比例,如 4 个 test, test1:test2:test3:test4=5:2:1:2 主循环跑 200 次,那么 test1:test2:test3:tesst4 的执行次数比例约等于 5:2:1:2
import net.grinder.scriptengine.groovy.junit.annotation.RunRate
import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
import net.grinder.plugin.http.HTTPRequest
import net.grinder.plugin.http.HTTPPluginControl
import net.grinder.script.GTest
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import HTTPClient.Cookie
import HTTPClient.CookieModule
import HTTPClient.HTTPResponse
import HTTPClient.NVPair
//@Repeat(100)
@RunWith(GrinderRunner)
class TestRunner {
public static GTest test
public static HTTPRequest request
public static NVPair[] headers = []
public static NVPair[] params = []
public static Cookie[] cookies = []
public static GTest test1
public static GTest test2
public static GTest test3
public static GTest test4
@BeforeProcess
public static void beforeProcess() {
HTTPPluginControl.getConnectionDefaults().timeout = 6000
test1 = new GTest(1, "test1") // 参数为 ID、显示名
test2 = new GTest(2, "test2")
test3 = new GTest(3, "test3")
test4 = new GTest(4, "test4")
request = new HTTPRequest()
grinder.logger.info("before process.");
}
@BeforeThread
public void beforeThread() {
test1.record(this, "test1")
test2.record(this, "test2")
test3.record(this, "test3")
test4.record(this, "test4")
grinder.statistics.delayReports=true;
grinder.logger.info("before thread.");
}
@Before
public void before() {
request.setHeaders(headers)
cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) }
grinder.logger.info("before thread. init headers and cookies");
}
@RunRate(50) // 数字代表百分比
@Test
public void test1(){
HTTPResponse result = request.GET("https://blog.csdn.net/")
if (result.statusCode == 301 || result.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
} else {
assertThat(result.statusCode, is(200));
}
}
@RunRate(20) // 数字代表百分比
@Test
public void test2(){
HTTPResponse result = request.GET("https://www.baidu.com")
if (result.statusCode == 301 || result.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
} else {
assertThat(result.statusCode, is(200));
}
}
@RunRate(10) // 数字代表百分比
@Test
public void test3(){
HTTPResponse result = request.GET("https://testerhome.com")
if (result.statusCode == 301 || result.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
} else {
assertThat(result.statusCode, is(200));
}
}
@RunRate(20) // 数字代表百分比
@Test
public void test4(){
HTTPResponse result = request.GET("http://www.runoob.com")
if (result.statusCode == 301 || result.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
} else {
assertThat(result.statusCode, is(200));
}
}
}
数据图标:
二、控制线程比例,如开了 4 个并发,4 个 test, test1:test2:test3:test4 线程比例等于=1:1:1:1
import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
import net.grinder.plugin.http.HTTPRequest
import net.grinder.plugin.http.HTTPPluginControl
import net.grinder.script.GTest
import net.grinder.script.Grinder
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import java.util.Date
import java.util.List
import java.util.ArrayList
import HTTPClient.Cookie
import HTTPClient.CookieModule
import HTTPClient.HTTPResponse
import HTTPClient.NVPair
import TestScriptObjectCalculate
/**
* @author 乐冉
*/
@RunWith(GrinderRunner)
class TestRunner {
public static GTest test
public static HTTPRequest request
public static NVPair[] headers = []
public static NVPair[] params = []
public static Cookie[] cookies = []
public static GTest test1
public static GTest test2
public static GTest test3
public static GTest test4
public static TestScriptObjectCalculate testScript
@BeforeProcess
public static void beforeProcess() {
HTTPPluginControl.getConnectionDefaults().timeout = 6000
test1 = new GTest(1, "test1") // 参数为 ID、显示名
test2 = new GTest(2, "test2")
test3 = new GTest(3, "test3")
test4 = new GTest(4, "test4")
request = new HTTPRequest()
grinder.logger.info("before process.");
}
@BeforeThread
public void beforeThread() {
test1.record(this, "test1")
test2.record(this, "test2")
test3.record(this, "test3")
test4.record(this, "test4")
grinder.statistics.delayReports=true;
grinder.logger.info("before thread.");
}
@Before
public void before() {
request.setHeaders(headers)
cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) }
grinder.logger.info("before thread. init headers and cookies");
}
@Test
public void test(){
int n =(int)new java.util.Random().nextInt(100)
grinder.logger.info(String.valueOf(n))
//控制线程数
int tid = grinder.threadNumber
int s = tid % 4
switch (s) {
case 0:
this.test1()
break;
case 1:
this.test2()
break;
case 2:
this.test3()
break;
case 3:
this.test4()
break;
}
}
public void test1(){
HTTPResponse result = request.GET("https://blog.csdn.net/")
if (result.statusCode == 301 || result.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
} else {
assertThat(result.statusCode, is(200));
}
}
public void test2(){
HTTPResponse result = request.GET("https://www.baidu.com")
if (result.statusCode == 301 || result.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
} else {
assertThat(result.statusCode, is(200));
}
}
public void test3(){
HTTPResponse result = request.GET("https://testerhome.com")
if (result.statusCode == 301 || result.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
} else {
assertThat(result.statusCode, is(200));
}
}
public void test4(){
HTTPResponse result = request.GET("http://www.runoob.com")
if (result.statusCode == 301 || result.statusCode == 302) {
grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", result.statusCode);
} else {
assertThat(result.statusCode, is(200));
}
}
}