本文是**FunTester**测试框架分布式性能测试功能拓展实践,是一种比较粗略的技术验证实践,技术方案采用
– [分布式性能测试框架用例方案设想(三)](https://mp.weixin.qq.com/s/hkSn4g9Z3sfWIV9-dOiS7Q)
中所设想场景,基于`Groovy`或者`Java`脚本,直接将脚本内容上传和下发给节点机器。
粗实现方案分成三块:**master调度机**、**slave测试机**和**server被测服务**。
* master调度机:处理用例、分配任务
* slave测试机:接受任务、执行用例
* server被测服务:提供测试接口
# docker镜像
内容同文章[基于docker的分布式性能测试框架功能验证(一)](https://mp.weixin.qq.com/s/7aa4HN82As3Zmf4DIVwv1A),这里不再赘述。
# master调度机
这里`master`节点接收到用例通过参数分配给`slave`测试机运行。由于只是功能性验证,我就选了一个`slave`节点。我依然值采用了`固定线程固定请求次数`的压测模型,用例就是功能验证的案例。
这里依然采用了`FunTester moco server`实现,分布式测试框架单节点版本正在内测,更多消息请留意近期公众号推文。
## master脚本
这里只返回一个测试脚本,这里就不用参数化了,有点麻烦。下面是脚本内容:
“`Java
package com.mocofun.moco.main
import com.alibaba.fastjson.JSONObject
import com.funtester.base.bean.Result
import com.funtester.utils.RWUtil
import com.mocofun.moco.MocoServer
class DcsServer3 extends MocoServer {
public static void main(String[] args) {
def server = getServer(12345)
def res = new JSONObject()
res.script = RWUtil.readTxtByString(“/Users/oker/IdeaProjects/funtester/src/test/groovy/com/funtest/groovytest/Share.groovy”)
server.get(urlStartsWith(“/m”)).response(obRes(Result.success(res)))
def run = run(server)
waitForKey(“fun”)
run.stop()
}
}
“`
`/Users/oker/IdeaProjects/funtester/src/test/groovy/com/funtest/groovytest/Share.groovy`脚本内容:
## 测试用例
“`Java
package com.funtest.groovytest
import com.funtester.config.Constant
import com.funtester.frame.execute.Concurrent
import com.funtester.frame.thread.RequestThreadTimes
import com.funtester.httpclient.ClientManage
import com.funtester.httpclient.FunLibrary
import com.funtester.utils.ArgsUtil
import org.apache.http.client.methods.HttpGet
class Share extends FunLibrary {
public static void main(String[] args) {
ClientManage.init(10, 5, 0, “”, 0);
def util = new ArgsUtil(args)
int thread = util.getIntOrdefault(0, 20);
int times = util.getIntOrdefault(1, 100);
String url = “http://localhost:12345/m”;
HttpGet get = getHttpGet(url);
Constant.RUNUP_TIME = 0;
RequestThreadTimes task = new RequestThreadTimes(get, times);
new Concurrent(task, thread, “本地固定QPS测试”).start();
}
public static void test(String params) {
main(params.split(COMMA))
}
}
“`
这里`test(String params)`为了做参数化特意加的,可忽略。
## slave测试机
这个逻辑通过简单的轮询去`master调度机`提供的接口获取测试任务或者测试用例。然后解析,执行测试用例。
“`Java
package com.funtest.groovytest
import com.funtester.frame.execute.ExecuteGroovy
import com.funtester.httpclient.FunLibrary
class Dcs3 extends FunLibrary {
public static void main(String[] args) {
while (true) {
// String url = “http://host.docker.internal:12345/m”
//请求此接口会返回一个用例,目前没有用对象封装
String url = “http://localhost:12345/m”
//请求此接口会返回一个用例,目前没有用对象封装
def get = getHttpGet(url)
def response = getHttpResponse(get)
if (response.getInteger(“code”) == 0) {
def data = response.getJSONObject(“data”)
def script = data.getString(“script”)
ExecuteGroovy.executeScript(script)
}
sleep(5.0)
fail()
}
}
}
“`
就是从服务拿到用例,然后使用默认参数运行测试用例。
控制台输出:
“`Java
INFO-> 当前用户:oker,工作目录:/Users/oker/IdeaProjects/funtester/,系统编码格式:UTF-8,系统Mac OS X版本:10.16
INFO-> 请求uri:http://localhost:12345/m , 耗时:463 ms , HTTPcode: 200
INFO-> =========预热完成,开始测试!=========
INFO-> 本地固定QPS测试进度:▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍▍ 100%
INFO-> 总计20个线程,共用时:0.754 s,执行总数:1933,错误数:0,失败数:0
INFO-> 数据保存成功!文件名:/Users/oker/IdeaProjects/funtester/long/data/本地固定QPS测试251800_20
INFO->
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
> {
> ① . “rt”:7,
> ① . “failRate”:0.0,
> ① . “threads”:20,
> ① . “deviation”:”10.27%”,
> ① . “errorRate”:0.0,
> ① . “executeTotal”:1933,
> ① . “qps2”:2563.660477453581,
> ① . “total”:1933,
> ① . “qps”:2857.1428571428573,
> ① . “startTime”:”2021-06-25 18:00:52″,
> ① . “endTime”:”2021-06-25 18:00:53″,
> ① . “mark”:”本地固定QPS测试251800″,
> ① . “table”:”eJzj5VIgCjybs+bpnA1PZ+96um5WYEDws63dL9ZPVTAyUCjJKEpNTCHOEAVeLl789gWlFhfk5xWnKoRk5qZaKVToFqcWZSbmKOSV5uooVOrmpqZkJuYRsoMIh+Rm5ilADLMyVMgt1slNrLAyMQeyqOILSsGjaR1ARJxPRm0ZtWXUllFbRm0ZtWXUllFbCFrRCET0sQlsBa1tQvUQTW17NK0ZiNCsorqNcA9BqVYgQlBYrKaiC+A+xO1RIigKXILuXYK+poar0H2Nj6KGS6jmAxqGFp1882haExANDgdR2XdDLDrI8CEA/wFbOg==”
> }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
Process finished with exit code 1
“`
![性能测试结果图形化展示](http://pic.automancloud.com/WX20210602-191519.png)
## server被测服务
内容通方案(一)这里依然不分享了。
日志如下:
“`Java
Content-Length: 1089
Content-Type: text/plain; charset=utf-8
{“code”:0,”data”:{“script”:”package com.funtest.groovytest;\r\n\r\nimport com.funtester.config.Constant;\r\nimport com.funtester.frame.execute.Concurrent;\r\nimport com.funtester.frame.thread.RequestThreadTimes;\r\nimport com.funtester.httpclient.ClientManage;\r\nimport com.funtester.httpclient.FunLibrary;\r\nimport com.funtester.utils.ArgsUtil;\r\nimport org.apache.http.client.methods.HttpGet;\r\n\r\nclass Share extends FunLibrary {\r\n\r\n public static void main(String[] args) {\r\n ClientManage.init(10, 5, 0, \”\”, 0);\r\n def util = new ArgsUtil(args)\r\n int thread = util.getIntOrdefault(0, 20);\r\n int times = util.getIntOrdefault(1, 100);\r\n String url = \”http://localhost:12345/m\”;\r\n HttpGet get = getHttpGet(url);\r\n Constant.RUNUP_TIME = 0;\r\n RequestThreadTimes task = new RequestThreadTimes(get, times);\r\n new Concurrent(task, thread, \”本地固定QPS测试\”).start();\r\n }\r\n\r\n public static void test(String params) {\r\n main(params.split(COMMA))\r\n }\r\n\r\n}\r\n”}}
Request received:
GET /favicon.ico HTTP/1.1
Host: localhost:12345
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
sec-ch-ua: ” Not;A Brand”;v=”99″, “Google Chrome”;v=”91″, “Chromium”;v=”91″
DNT: 1
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Referer: http://localhost:12345/m
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
sec-gpc: 1
content-length: 0
Response return:
HTTP/1.1 400
“`
> # **Have Fun ~ Tester !**
#### **FunTester**,一群有趣的灵魂,腾讯云&Boss认证作者,GDevOps官方合作媒体。
—-
– [FunTester测试框架架构图初探](https://mp.weixin.qq.com/s/bcMbVDkWbHSXjZFDeFyJsQ)
– [10万QPS,K6、Gatling和FunTester终极对决!](https://mp.weixin.qq.com/s/HZvBPUEaws72hlwb1QXzuw)
– [单机12万QPS——FunTester复仇记](https://mp.weixin.qq.com/s/4IBaEpj3TEHY_2ZdGOON0g)
– [超万字回顾FunTester的前世今生](https://mp.weixin.qq.com/s/bEW6DK86qwgAWnjdkUGiZA)
– [生产环境中进行自动化测试](https://mp.weixin.qq.com/s/JKEGRLOlgpINUxs-6mohzA)
– [编写测试用例的技巧](https://mp.weixin.qq.com/s/zZAh_XXXGOyhlm6ebzs06Q)
– [成为自动化测试的7种技能](https://mp.weixin.qq.com/s/e-HAGMO0JLR7VBBWLvk0dQ)
– [物联网测试](https://mp.weixin.qq.com/s/B_JI4DANxoOq4HurxZC65Q)
– [测试为何会错过Bug](https://mp.weixin.qq.com/s/UFHy8OwZjnMkB70roIS-zQ)
– [Selenium自动化最佳实践技巧(上)](https://mp.weixin.qq.com/s/lZww1azmncMMMHRY0_yKqA)
– [Selenium自动化最佳实践技巧(中)](https://mp.weixin.qq.com/s/9D0lUZ-XKHiukNeRqp6zOQ)
– [Selenium自动化最佳实践技巧(下)](https://mp.weixin.qq.com/s/opVik2ZxmTBurIBoa4yipQ)
– [Socket接口异步验证实践](https://mp.weixin.qq.com/s/bnjHK3ZmEzHm3y-xaSVkTw)
– [Groovy在JMeter中处理cookie](https://mp.weixin.qq.com/s/DCnDjWaj2aiKv5HVw3-n6A)
**点击阅读阅文,查看FunTester历史原创集合**
本文来自投稿,不代表TakinTalks稳定性技术交流平台立场,如若转载,请注明出处:https://news.shulie.io/?p=3447