nGrinder 的 Groovy 脚本使用指南(HTTP 请求详解)

请确定您已经了解了 nGrinder 的 Groovy 脚本结构:nGrinder 的 Groovy 脚本使用指南(Groovy 脚本结构)

在 nGrinder 上创建 Groovy 脚本时,会自动生成一个基础的脚本,让我们将其拆分说明

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

/**
 *
 * @author aub
 */
@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.aub.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("wd", "nGrinder"))
        params = paramList.toArray()

        // 设置 cookie 信息
        List cookieList = new ArrayList()
        cookieList.add(new Cookie("username", "aub", "www.aub.com", "/", new Date(32503647599000L), 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/s", 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 注释的方法,定义了在 进程 被调用之前应执行的行为

@BeforeProcess
public static void beforeProcess() {
    // HTTP请求超时时间,单位毫秒
    HTTPPluginControl.getConnectionDefaults().timeout = 6000
    test = new GTest(1, "www.aub.com")
    request = new HTTPRequest()

    // 设置请求头数据
    List<NVPair> headerList = new ArrayList<NVPair>()
    headerList.add(new NVPair("test_header", "test_header_value"))
    headers = headerList.toArray()

    // 设置请求参数
    List<NVPair> paramList = new ArrayList<NVPair>()
    paramList.add(new NVPair("wd", "nGrinder"))
    params = paramList.toArray()

    // 设置 cookie 信息
    List<Cookie> cookieList = new ArrayList<Cookie>()
    cookieList.add(new Cookie("username", "aub", "www.aub.com", "/", new Date(32503647599000L), 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 注释的方法,定义了在 线程 被调用之前应执行的行为

@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 只脚本对象,这里是 thismethodName 是需要统计的方法名,通常都是被 @Test 注释的方法。如果未配置,方法会正常执行,但是没有统计结果数据,每一个被 @Test 注释的方法都是一个整体事务,在运行测试时,即便里面有 多次 HTTP 请求也只做一次统计
  2. 配置延迟报告统计结果
  3. 最后打印了执行日志

初始化测试级别数据

使用 @Before 注释的方法,定义每个被 @Test 注解的方法被执行前应执行的行为

@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 注释的方法,定义测试行为,被执行多次

@Test
public void test() {
    // 发起 GET 请求
    HTTPResponse result = request.GET("http://www.baidu.com/s", 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 对象还有其他的请求方法:POSTPUTDELETE 等。

思考

  1. 如果测试脚本的请求头都一样,是否可以放到 @BeforeThread 或者 @BeforeProcess 中呢,这样是对测试脚本本身的性能是否会有帮助呢?

你可能感兴趣的:(test)