티스토리 뷰

출처
https://github.com/naver/ngrinder/wiki/Frequently-Asked-Question
https://velog.io/@max9106/nGrinderPinpoint-test2

https://flowlog.tistory.com/80

 

Frequently Asked Question

enterprise level performance testing solution. Contribute to naver/ngrinder development by creating an account on GitHub.

github.com

 

 

nGrinder와 Pinpoint를 이용한 성능 / 부하 테스트2 - 시나리오 작성

테스트를 진행하기 위해서는 먼저 시나리오 기반으로 스크립트를 작성해야합니다. nGrinder는 Groovy나 Jython를 지원합니다.

velog.io

 

 

[성능테스트] nGrinder Script POST 해보기

지난 포스팅에 nGrinder 설치 및 GET 테스트를 마쳤다. 이제 2가지 테스트를 해볼 건데, 로그인 시도와 로그인한 사용자만 이용할 수 있는 페이지를 요청하는 것이다. 필자가 구현해둔 application은 아

flowlog.tistory.com

 

 

먼저 이번에 작성한 시나리오는
로그인 -> 장바구니에 상품 담기 -> 주문 순으로 이루어졌다.

import static net.grinder.script.Grinder.grinder
import static org.junit.Assert.*
import static org.hamcrest.Matchers.*
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 static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder

import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import org.ngrinder.http.HTTPRequest
import org.ngrinder.http.HTTPRequestControl
import org.ngrinder.http.HTTPResponse
import org.ngrinder.http.cookie.Cookie
import org.ngrinder.http.cookie.CookieManager

/**
* A simple example using the HTTP plugin that shows the retrieval of a single page via HTTP.
*
* This script is automatically generated by ngrinder.
*
* @author admin
*/
@RunWith(GrinderRunner)
class TestRunner {

	public static GTest test1
	public static GTest test2
	public static GTest test3
	
	public static HTTPRequest request
	public static Map<String, String> headers = [:]
	public static Map<String, Object> params = [:]
	public static List<Cookie> cookies = []
	
	//request에 담을 토큰 값 설정
	private static String token

	@BeforeProcess
	public static void beforeProcess() {
		HTTPRequestControl.setConnectionTimeout(300000)
		
		test1 = new GTest(1, "POST /api/members/login")
		test2 = new GTest(2, "POST /api/products/cart/{productId}")
		test3 = new GTest(3, "POST /api/products/order-one")
		
		request = new HTTPRequest()
		
		grinder.logger.info("before process.")
	}

	@BeforeThread
	public void beforeThread() {
		test1.record(this, "test1")
		test2.record(this, "test2")
		test3.record(this, "test3")
		
		grinder.statistics.delayReports = true
		grinder.logger.info("before thread.")
	}
	
	//로그인
	@Test
	public void test1() {

		
		// 로그인 API에 요청을 보내서 JWT 토큰을 받아옴
		HTTPResponse response = request.POST("http://api.whitenation.shop/api/members/login", [username: "zser30", password: "abcd1234?"])
		
		//grinder.logger.info("처음에 추가되는 토큰: {}", response.getHeader("Authorization").toString().substring(15))
		
		//토큰 앞에 붙는 쓸데없는 String 제거
		token = response.getHeader("Authorization").toString().substring(15);
		
		//헤더에 넣어줌
		headers.put("Authorization", token)
		
		//헤더 가져옴
		def result = response.getHeader("Authorization");
		//grinder.logger.info("header: {}", result)
		
		if (response.statusCode == 301 || response.statusCode == 302) {
			grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode)
		} else {
			assertThat(response.statusCode, is(200))
		}
		
		grinder.logger.info("response: {}", response.getBodyText())
	}
	
	// 장바구니에 상품 추가
	@Test
		public void test2() {
		def productId = "4"
		
		 //grinder.logger.info("봐야되는거: {}", headers)
		 //로그인 할 때 가져온 걸로 request에 담음
		request.setHeaders(headers)
		
		//grinder.logger.info("header: {}", headers)
		HTTPResponse response = request.POST("http://api.whitenation.shop/api/products/cart/" + productId);
		
		//response가 성공하면 201로 찍힘
		assertThat(response.statusCode, is(201));
		
		 //grinder.logger.info("response: {}", response.getBodyText())
		
		if (response.statusCode == 301 || response.statusCode == 302) {
			grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode)
		} else {
			assertThat(response.statusCode, is(201))
		}
		
		//grinder.logger.info("response: {}", response.getBodyText())
	}
	

	@Test
		public void test3() {
		 // 상품 주문
		 
		request.setHeaders(headers)
		
		params = ["productId": 4, "quantity": 2]
		
		//setBody로 하면 타입이 안맞는다고 하면서 에러남
		HTTPResponse response = request.POST("http://api.whitenation.shop/api/products/order-one",params)
		assertThat(response.statusCode, is(200))

		
		if (response.statusCode == 301 || response.statusCode == 302) {
			grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode)
		} else {
			assertThat(response.statusCode, is(200))
		}
		
		//grinder.logger.info("response: {}", response.getBodyText())
	}
}

 

 

GTest 객체는 각각 테스트 시나리오,

예를 들어 하나당 로그인, 장바구니 담기 등에 해당되는 것이다.

 

@BeforeProcess -> 테스트가 시작되기 전에 실행되는 메서드. 한 번 실행

@BeforeThread -> 스레드가 시작되기 전에 실행되는 메서드. 스레드가 시작될 때마다 실행.

@BeforeProcess -> @BeforeThread -> HTTP 요청 순서로 실행된다.

 

댓글