# nGrinderLearn **Repository Path**: testdevops/nGrinderLearn ## Basic Information - **Project Name**: nGrinderLearn - **Description**: nGrinder是一个压力测试平台,使您可以同时执行脚本创建,测试执行,监视和结果报告生成器。开源nGrinder通过消除不便并提供集成环境,提供简单的方法来进行压力测试。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 2 - **Created**: 2018-10-18 - **Last Updated**: 2022-04-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # nGrinder ## nGrinder简介 nGrinder是一个压力测试平台,使您可以同时执行脚本创建,测试执行,监视和结果报告生成器。开源nGrinder通过消除不便并提供集成环境,提供简单的方法来进行压力测试。 ### 特征 - 使用Jython或Groovy脚本创建测试场景并使用多个代理在JVM中生成压力。 - 使用自定义库(jar,py,maven依赖项)扩展测试。它是无限的。 - 为项目管理,监控,结果管理和报告管理提供基于Web的界面。 - 在IDE中开发和测试Groovy脚本,并在分布式代理中运行它。 - 同时运行多个测试。分配预先安装的多个代理以最大化每个代理的利用率。 - 在多个网络区域上部署代理。在各种网络位置执行测试 - 嵌入Subversion来管理脚本。 - 允许监控产生压力的代理状态和接收压力的目标机器 - 经过验证的解决方案,用于测试拥有超过1亿用户的大型系统。 ### 下载 您可以通过以下链接下载最新版本 - ### 文档 您可以在以下链接中找到安装指南。 - 您可以在以下链接中找到用户指南。 - ## 总体架构 nGrinder 是一款在一系列机器上执行 Groovy 或 Jython 测试脚本的应用,内部引擎是基于 **Grinder**。 nGrinder 使用 controller 和 agent 分别包装了 Grinder 的 console 和 agent ,而且扩展了多种功能使其能够支持并发测试。 ### 组件介绍 #### Controller - 提供性能测试的web接口。 - 协调测试进程。 - 整理和显示测试的统计结果 - 让用户创建和修改脚本。 - nGrinder 从 3.1 版本开始支持 controller 集群 主要就是我们下载的war包使用tomcat容器运行的平台 ,相当于前端控制器。 #### Agent - 在代理服务器上加载运行测试进程和线程 - 监控目标机器的系统性能(例如:CPU/MEMORY) 由前端控制器操作实际支配的肉鸡,命运较惨,主要执行前端控制器下达的各种任务。 运行在肉鸡系统中有一定先决条件,需要安装**Jdk1.8**; ## 测试服务器安装Controller - 在下载地址下载最新版本[**ngrinder-controller-3.4.2.war**](https://github.com/naver/ngrinder/releases/download/ngrinder-3.4.2-20180830/ngrinder-controller-3.4.2.war) - 修改war包名称为ngrinder(或者其他 你开心就好) - 准备tomcat运行环境服务器、保证安装Jdk1.8和tomcat 并正常运行。 - 将ngrinder.war包拷贝至服务器tomcat下/webhapps目录下 - 启动tomcat服务器 - 访问http://localhost:8080/ngrinder ## 测试肉鸡服务器安装Agent - 准备Agent肉鸡服务器 若干台需要安装Jdk1.8; - 登录Controller控制器网站登录 - 用户名下展开后点击下载Agent(代理) - 将Agent代理拷贝至肉鸡服务器 - 解压缩后运行run.agent.bat. ## 被测服务器安装Monitor - Agent服务器安装好Agent后是不需要安装Monitor的自动集成了 - 需要在被测试的机器中安装Monitor以监控在测试期间被测服务器的性能表现; - 登录Controller控制器网站登录、用户下展开后点击下载监控(Monitor) - 拷贝至被测试服务器运行run.monitor.bat ## 快速入门测试 - 登录系统后有个快速开始的框,在此输入http://www.baidu.com,点击开始测试。 - 这时候进入第二个页面配置运行参数 agent(?需要几台机器) 持续多长时间 - 点击保存并开始,立即运行; - 查看运行后的测试报告; ## 脚本开发介绍 ```java import HTTPClient.Cookie import HTTPClient.CookieModule import HTTPClient.HTTPResponse import HTTPClient.NVPair import net.grinder.plugin.http.HTTPPluginControl import net.grinder.plugin.http.HTTPRequest 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 static net.grinder.script.Grinder.grinder import static org.hamcrest.Matchers.is import static org.junit.Assert.assertThat @RunWith(GrinderRunner) class TestRunner { public static GTest test public static HTTPRequest request public static NVPair[] headers = [] public static NVPair[] params = [] public static Cookie[] cookies = [] @BeforeProcess public static void beforeProcess() { HTTPPluginControl.getConnectionDefaults().timeout = 6000 test = new GTest(1, "www.baidu.com") request = new HTTPRequest() // 设置请求头数据 List headerList = new ArrayList() headerList.add(new NVPair("test_header", "test_header_value")) headers = headerList.toArray() // 设置请求参数 List paramList = new ArrayList() paramList.add(new NVPair("paramname", "vaule")) params = paramList.toArray() // 设置 cookie 信息 List cookieList = new ArrayList() cookieList.add(new Cookie("username", "testname", "www.baidu.com", "/", new Date(), false)) cookies = cookieList.toArray() // 记录日志 grinder.logger.info("before process.") } @BeforeThread public void beforeThread() { test.record(this, "test") // 配置延迟报告统计结果 grinder.statistics.delayReports = true // 记录日志 grinder.logger.info("before thread.") } @Before public void before() { // 设置本次请求头 request.setHeaders(headers) // 设置本次请求的 cookies cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) } // 记录日志 grinder.logger.info("before thread. init headers and cookies") } @Test public void test() { HTTPResponse result = request.GET("http://www.baidu.com", params) 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 static GTest test public static HTTPRequest request public static NVPair[] headers = [] public static NVPair[] params = [] public static Cookie[] cookies = [] ``` 1. 定义 GTest 静态变量 `test` 2. 定义 HTTPRequest 静态变量 `request`,用于发送 HTTP 请求 3. 定义 NVPair 数组 `headers` ,用于存放通用的请求头数据 4. 定义 NVPair 数组 `params` ,用于存放请求参数数据 5. 定义 Cookie 数组 `cookies` ,用于存放通用的 cookie 数据 ### 初始化进程级数据 使用 `@BeforeProcess` 注释的方法,定义了在 **进程** 被调用之前应执行的行为 ```java @BeforeProcess public static void beforeProcess() { // HTTP请求超时时间,单位毫秒 HTTPPluginControl.getConnectionDefaults().timeout = 6000 test = new GTest(1, "www.baidu.com") request = new HTTPRequest() // 设置请求头数据 List headerList = new ArrayList() headerList.add(new NVPair("test_header", "test_header_value")) headers = headerList.toArray() // 设置请求参数 List paramList = new ArrayList() paramList.add(new NVPair("paramname", "vaule")) params = paramList.toArray() // 设置 cookie 信息 List cookieList = new ArrayList() cookieList.add(new Cookie("username", "testname", "www.baidu.com", "/", new Date(), false)) cookies = cookieList.toArray() // 记录日志 grinder.logger.info("before process.") } ``` 1. 首先设置了HTTP请求超时时间,单位毫秒. 2. GTest是对测试记录进行统计的单元,脚本内,每个 GTest 对象都使用唯一的编号定义,可以有描述信息,使用 GTest 的构造方法 `GTest(int number, String description)` 创建。如果创建了多个编号一样的对象,最后只会选用第一个 3. 使用 `new HTTPRequest()` 创建 HTTPRequest 对象,用于发起 HTTP 请求 4. 请求头和请求参数,都是键值对对象 NVPair 类型的数组 5. 可以通过 `Cookie(String name, String value, String domain, String path, Date expires, boolean secure)` 构造 cookie 对象,然后存放到相应的数组中,方便后面使用 6. 最后打印了执行日志 ### 初始化线程级数据 使用 `@BeforeThread` 注释的方法,定义了在 **线程** 被调用之前应执行的行为 ```java @BeforeThread public void beforeThread() { test.record(this, "test") // 配置延迟报告统计结果 grinder.statistics.delayReports = true // 记录日志 grinder.logger.info("before thread.") } ``` 1. 使用 GTest 的 `record(Object target, String methodName)` 给 GTest 配置需要进行统计的方法,target 只脚本对象,这里是 this, methodName 是需要统计的方法名,通常都是被 @Test 注释的方法。如果未配置,方法会正常执行,但是没有统计结果数据,每一个被 @Test 注释的方法都是一个整体事务,在运行测试时,即便里面有 多次 HTTP 请求也只做一次统计。 2. 配置延迟报告统计结果 3. 最后打印了执行日志 ### 初始化测试级别数据 使用 `@Before` 注释的方法,定义每个被 @Test 注解的方法被执行前应执行的行为 ```java @Before public void before() { // 设置本次请求头 request.setHeaders(headers) // 设置本次请求的 cookies cookies.each { CookieModule.addCookie(it, HTTPPluginControl.getThreadHTTPClientContext()) } // 记录日志 grinder.logger.info("before thread. init headers and cookies") } ``` 1. 设置本次请求头 2. 设置本次请求的 cookies 3. 最后打印了执行日志 ### 定义测试行为 使用 `@Test` 注释的方法,定义测试行为,被执行多次 ```java @Test public void test() { // 发起 GET 请求 HTTPResponse result = request.GET("http://www.baidu.com", params) 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)) } } ``` 1. 通过 `request.GET` 方法发起 HTTP 的 GET 请求,也可以使用它的重载方法,在次数执行请求头 2. 根据请求的返回结果分别进行处理,如果是 HTTP 的返回状态码为重定向,则打日志,当然您可以做其他处理,否则,使用断言 `assertThat` 方法进行结果验证,会自动进入统计结果中。 3. `HTTPRequest` 对象还有其他的请求方法:`POST`,`PUT`,`DELETE` 等。