[ Spring ] nGrinder를 활용한 부하 테스트 - 2 ( 시나리오 작성 및 테스트 )

5tr1ker·2024년 2월 25일
0

nGrinder

목록 보기
2/2
post-thumbnail

개요

해당 시나리오는 저의 개인 프로젝트인 myStory 를 기반으로 테스트를 진행할 것 이며, 해당 프로젝트의 깃 주소는 해당 링크 를 참고해주세요.

시나리오 수립

  • 시나리오 1 ( 게시글 )
    회원가입 -> 로그인 -> 게시글 목록 조회 -> 게시글 조회 -> 댓글 작성 -> 포스트 추천 -> 게시글 작성 -> 게시글 수정 -> 게시글 탐색 -> 게시글 삭제

  • 시나리오 2 ( 모임 )
    회원가입 -> 로그인 -> 모임 목록 조회 -> 모임 생성 -> 모임 참여 -> 나의 모임 목록 조회 -> 해당 모임 상세보기 조회 -> 해당 모임 페이지 이동 -> 모임 내 예약 추가 -> 모임 내 예약 참여 -> 모임 내 예약 탈퇴 -> 모임 수정 -> 모임 상세 탐색 -> 모임 삭제

  • 시나리오 3 ( 사용자 )
    회원가입 -> 로그인 -> 마이 페이지 -> 개인 정보 변경 -> 재 로그인 -> 계정 탈퇴

테스트 진행

위의 사진처럼 Groovy 라는 언어를 활용해 작성을 하고 검증 버튼을 누르면 시험적으로 1회 실행이 되며, 이는 실제 프로젝트에도 요청이 전송이 됩니다.

General error during conversion: Unsupported class file major version 61 >에러

class file major version 61은 로드 하려고 시도하고 있는 클래스 파일이 자바 17 혹은 그 이상의 버전에서 컴파일이 되었으며, 자바 17 이상에서만 사용 될 수 있을 때 발생한다고 합니다.

해결방법
JDK SDK 버전 변경 ( 버전 8 추천 )
실행시 Java HOME 지정

시나리오 1 테스트 결과

평균 MTT : 52.5ms

가장 중요한 것은 MTT(=Mean Test Time) 으로 1회 테스트 수행 시 걸리는 시간을 의미합니다. ( 단위는 ms )

MMT가 1000을 넘을 시 1초가 걸린다는 뜻인데 최소 1 이하로 줄여야 합니다.
만약 MMT가 1000이 넘어가는 부분이 있다면 sql 튜닝을 하여 최적화 할 수 있도록 합니다.

ID 값은 위의 시나리오 Groovy 코드에서 각 부분에 해당합니다. beforeThread() 메서드 안에 record(this, "test00") 부분은 회원가입 테스트 부분만 해당됩니다.
만약 ID 값이 2 번인 곳에서 병목이 발생한다면, 해당 record(this, "test02") 로 지정된 게시글 목록 조회 부분을 쿼리 최적화를 진행해야 합니다.

시나리오 2 테스트 결과

평균 MTT : 43.5ms

시나리오 3 테스트 결과

평균 MTT : 13ms

전체 API 테스트 결과

시나리오 1 ( 52.5ms ) , 시나리오 2 ( 43.5ms ) , 시나리오 3 ( 13ms )
전체 평균 MTT : 36.3ms
최고 MTT : 182ms

시나리오 코드

시나리오 1 코드

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 org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import org.apache.hc.core5.http.ContentType
import groovy.json.JsonSlurper

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
import org.ngrinder.http.multipart.MultipartEntityBuilder

/**
* 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 test0
	public static GTest test1
	public static GTest test2
	public static GTest test3
	public static GTest test4
	public static GTest test5
	public static GTest test6
	public static GTest test7
	public static GTest test8
	public static GTest test9
	public static GTest test10
	
	public static HTTPRequest request = new HTTPRequest()
	public Map<String, String> headers = [:]
	public Map<String, Object> params = [:]
	public List<Cookie> cookies = []

	@BeforeProcess
	public static void beforeProcess() {
		HTTPRequestControl.setConnectionTimeout(300000)
		test0 = new GTest(0, "127.0.0.1")
		test1 = new GTest(1, "127.0.0.1")
		test2 = new GTest(2, "127.0.0.1")
		test3 = new GTest(3, "127.0.0.1")
		test4 = new GTest(4, "127.0.0.1")
		test5 = new GTest(5, "127.0.0.1")
		test6 = new GTest(6, "127.0.0.1")
		test7 = new GTest(7, "127.0.0.1")
		test8 = new GTest(8, "127.0.0.1")
		test9 = new GTest(9, "127.0.0.1")
		test10 = new GTest(10, "127.0.0.1")
		grinder.logger.info("before process.")
	}

	@BeforeThread
	public void beforeThread() {
		test0.record(this, "test00")
		test1.record(this, "test01")
		test2.record(this, "test02")
		test3.record(this, "test03")
		test4.record(this, "test04")
		test5.record(this, "test05")
		test6.record(this, "test06")
		test7.record(this, "test07")
		test8.record(this, "test08")
		test9.record(this, "test09")
		test10.record(this, "test10")
		grinder.statistics.delayReports = true
		grinder.logger.info("before thread.")
	}

	@Before
	public void before() {
		request = new HTTPRequest()
		request.setHeaders(headers)
		CookieManager.addCookies(cookies)
		grinder.logger.info("before. init headers and cookies")
	}

// 01. 로그인 -> 02. 게시글 목록 조회 -> 게시글 조회 -> 댓글 작성 -> 추천 -> 게시글 목록 조회 -> 게시글 조회 -> 게시글 작성 -> 게시글 목록 조회 -> 방금 작성한 게시글 조회 -> 게시글   수정 -> 게시글 조회 -> 게시글 삭제
	
	// 00. 회원가입
	@Test
	public void test00() {
		String url = "http://127.0.0.1:8080/registers";
		String body = "{\"id\": \""+CommonData.userId+"\" , \"email\": \"" + CommonData.userEmail + "\", \"password\": \""+CommonData.userPassword+"\" , \"checkPassword\" : \"" + CommonData + "\"}"
		grinder.logger.info(body);
		HTTPResponse response = request.POST(url, body.getBytes())

		if (response.statusCode == 400) {
			grinder.logger.warn("is exist Account.", response.statusCode)
		} else {
			assertThat(response.statusCode, is(200))
		}
	}
	
	// 01. 로그인
	@Test
	public void test01() {
		String url = "http://127.0.0.1:8080/logins";
		String body = "{\"id\": \""+CommonData.userId+"\" , \"password\": \""+CommonData.userPassword+"\"}"
		grinder.logger.info(body);
		HTTPResponse response = request.POST(url, body.getBytes())

		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))
		}
		
		cookies = CookieManager.getCookies();
		CookieManager.addCookies(cookies)
	}
	
	// 02. 게시글 목록 조회
	@Test
	public void test02() {
		String url = "http://127.0.0.1:8080/posts"
		HTTPResponse response = request.GET(url)

		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))
		}
	}
	
	// 03. 게시글 조회
	@Test
	public void test03() {
		String url_01 = "http://127.0.0.1:8080/posts/" + CommonData.postId
		String url_02 = "http://127.0.0.1:8080/posts/views/" + CommonData.postId
		HTTPResponse response_01 = request.GET(url_01)
		HTTPResponse response_02 = request.PATCH(url_02)

		if (response_01.statusCode == 301 || response_01.statusCode == 302) {
			grinder.logger.warn("Warning. The response may not be correct. The response code was {}.", response.statusCode)
		} else {
			assertThat(response_01.statusCode, is(200))
		}
	}
	
	// 04. 댓글 작성
	@Test
	public void test04() {
		String url = "http://127.0.0.1:8080/comments";
		String body = "{\"content\":\"Commentcotnent\", \"postId\": "+CommonData.postId+"}"
		grinder.logger.info(body);
		HTTPResponse response = request.POST(url, body.getBytes())

		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))
		}
	}
	
	// 05. 포스트 추천
	@Test
	public void test05() {
		String url = "http://127.0.0.1:8080/posts/likes/" + CommonData.postId;
		HTTPResponse response = request.PATCH(url)

		if (response.statusCode == 400) {
			grinder.logger.warn("is already Like {}.", response.statusCode)
		} else {
			assertThat(response.statusCode, is(200))
		}
	}
	
	// 06. 게시글 작성
	@Test
	public void test06() {
		String url = "http://127.0.0.1:8080/posts";
		def multipart = MultipartEntityBuilder.create()
                .addEntity("postRequest", "{\"tags\":[\"tag1\",\"tag2\",\"tag3\"], \"blockComment\" : 0 , \"privatePost\" : 0 , \"title\" : \"title\" , \"content\" : \"content\"}" , ContentType.APPLICATION_JSON)
				.addEntity("multipartFiles", new File("./resources/test.png"))
                .build();
		
		HTTPResponse response = request.POST(url, multipart)
		
		// 마지막에 작성된 게시글 id 값 가져오기
		String url_01 = "http://127.0.0.1:8080/posts?size=1&offset=1";
		HTTPResponse response_2 = request.GET(url_01)
		def jsonMsg = new JsonSlurper().parseText(response_2.getBodyText())
		CommonData.customPostId = jsonMsg.data.numbers[0].toString();

		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))
		}
	}
	
	// 07. 게시글 수정
	@Test
	public void test07() {
		String url = "http://127.0.0.1:8080/posts/" + CommonData.customPostId;
		def multipart = MultipartEntityBuilder.create()
                .addEntity("postRequest", "{\"tags\":[\"tag11\",\"tag22\",\"tag33\"], \"deletedFileIds\":[], \"blockComment\" : 0 , \"privatePost\" : 0 , \"title\" : \"title22\" , \"content\" : \"content22\"}" , ContentType.APPLICATION_JSON)
                .build();
		
		HTTPResponse response = request.PUT(url, multipart)
		
		grinder.logger.warn(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(200))
		}
	}
	
	// 08. 게시글 탐색 _ 키값 탐색
	@Test
	public void test08() {
		String url = "http://127.0.0.1:8080/posts/search/title";
		HTTPResponse response = request.GET(url)

		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))
		}
	}
	
	// 09. 게시글 탐색 _ 태그 검색
	@Test
	public void test09() {
		String url = "http://127.0.0.1:8080/posts/search/tags/a";
		HTTPResponse response = request.GET(url)

		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))
		}
	}
	
	// 10. 게시글 d삭제
	@Test
	public void test10() {
		String url = "http://127.0.0.1:8080/posts/" + CommonData.customPostId;
		HTTPResponse response = request.DELETE(url)

		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))
		}
	}
	
	class CommonData {
		public static final String userId = "tester"
		public static final String userEmail = "tester@naver.com"
		public static final String userPassword = "tester"
		public static final int postId = 1
		public static String customPostId = "1";
	}
}

모두 작성이 되었다면 웹 페이지 상단에 '성능 테스트' 버튼을 눌러 들어가면 다음과 같은 화면이 뜹니다.

에이전트 갯수, 가상 사용자, 프로세스, 쓰레드 숫자를 입력하고 실행할 스크립트를 정한 다음 우측 위에 복제 후 시작 을 눌러주면 됩니다.

설정한 시간이 끝나면 테스트를 마치며 상세 보고서를 볼 수 있습니다.

시나리오 2 코드

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 org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import org.apache.hc.core5.http.ContentType
import groovy.json.JsonSlurper

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
import org.ngrinder.http.multipart.MultipartEntityBuilder

/**
* 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 test01
	public static GTest test02
	public static GTest test03
	public static GTest test04
	public static GTest test05
	public static GTest test06
	public static GTest test07
	public static GTest test08
	public static GTest test09
	public static GTest test10
	public static GTest test11
	public static GTest test12
	
	public static HTTPRequest request
	public Map<String, String> headers = [:]
	public Map<String, Object> params = [:]
	public List<Cookie> cookies = []
	String customMeetingId = "1";
	String customReservationId = "1";
	
	@BeforeProcess
	public static void beforeProcess() {
		HTTPRequestControl.setConnectionTimeout(300000)
		test01 = new GTest(1, "127.0.0.1")
		test02 = new GTest(2, "127.0.0.1")
		test03 = new GTest(3, "127.0.0.1")
		test04 = new GTest(4, "127.0.0.1")
		test05 = new GTest(5, "127.0.0.1")
		test06 = new GTest(6, "127.0.0.1")
		test07 = new GTest(7, "127.0.0.1")
		test08 = new GTest(8, "127.0.0.1")
		test09 = new GTest(9, "127.0.0.1")
		test10 = new GTest(10, "127.0.0.1")
		test11 = new GTest(11, "127.0.0.1")
		test12 = new GTest(12, "127.0.0.1")
		request = new HTTPRequest()
		grinder.logger.info("before process.")
	}

	@BeforeThread
	public void beforeThread() {
		test01.record(this, "test01")
		test02.record(this, "test02")
		test03.record(this, "test03")
		test04.record(this, "test04")
		test05.record(this, "test05")
		test06.record(this, "test06")
		test07.record(this, "test07")
		test08.record(this, "test08")
		test09.record(this, "test09")
		test10.record(this, "test10")
		test11.record(this, "test11")
		test12.record(this, "test12")
		grinder.statistics.delayReports = true
		grinder.logger.info("before thread.")
	}

	@Before
	public void before() {
		request.setHeaders(headers)
		CookieManager.addCookies(cookies)
		grinder.logger.info("before. init headers and cookies")
	}

	// 회원가입 -> 로그인 -> 모임 목록 조회 -> 모임 생성 -> 모임 참여 -> 나의 모임 목록 조회 -> 해당 모임 상세보기 조회 -> 해당 모임 페이지 이동 -> 모임 내 예약 추가 -> 모임 내 예약 참여 -> 모임 내 예약 탈퇴 -> 모임 수정 -> 모임 상세 탐색 -> 모임 삭제
	// 00. 회원가입
	@Test
	public void test00() {
		String url = "http://127.0.0.1:8080/registers";
		String body = "{\"id\": \""+CommonData.userId+"\" , \"email\": \"" + CommonData.userEmail + "\", \"password\": \""+CommonData.userPassword+"\" , \"checkPassword\" : \"" + CommonData + "\"}"
		grinder.logger.info(body);
		HTTPResponse response = request.POST(url, body.getBytes())

		if (response.statusCode == 400) {
			grinder.logger.warn("is exist Account.", response.statusCode)
		} else {
			assertThat(response.statusCode, is(200))
		}
	}
	
	// 01. 로그인
	@Test
	public void test01() {
		String url = "http://127.0.0.1:8080/logins";
		String body = "{\"id\": \""+CommonData.userId+"\" , \"password\": \""+CommonData.userPassword+"\"}"
		grinder.logger.info(body);
		HTTPResponse response = request.POST(url, body.getBytes())

		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))
		}
		
		cookies = CookieManager.getCookies();
		CookieManager.addCookies(cookies)
	}
	
	// 02. 모임 목록 조회
	@Test
	public void test02() {
		String url = "http://127.0.0.1:8080/meeting"
		HTTPResponse response = request.GET(url)
		
		String url_2 = "http://127.0.0.1:8080/meeting/count"
		HTTPResponse response_2 = request.GET(url_2)

		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))
		}
	}
	
	// 03. 모임 생성
	@Test
	public void test03() {
		String url = "http://127.0.0.1:8080/meeting"
		def multipart = MultipartEntityBuilder.create()
                .addEntity("meeting", "{\"locateX\" : 0 , \"locateY\" : 0 , \"address\" : \"address\" , \"title\" : \"title\" , \"description\" : \"description\" , \" detailAddress\" : \"detailAddress\" , \"maxParticipants\" : 10}" , ContentType.APPLICATION_JSON)
				.addEntity("image", new File("./resources/test.png"))
                .build();
				
		HTTPResponse response = request.POST(url , multipart)
		
		String url_01 = "http://127.0.0.1:8080/meeting?size=1&offset=1"
		HTTPResponse response_2 = request.GET(url_01)
		def jsonMsg = new JsonSlurper().parseText(response_2.getBodyText())
		customMeetingId = jsonMsg.meetingId[0].toString()

		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))
		}
	}
	
	// 04. 모임 참여
	@Test
	public void test04() {
		String url = "http://127.0.0.1:8080/meeting/" + customMeetingId;
		HTTPResponse response = request.POST(url)
		grinder.logger.warn("ababcabcba");

		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(400))
		}
	}
	
	// 05. 나의 모임 목록 조회
	@Test
	public void test05() {
		String url = "http://127.0.0.1:8080/meeting/user"
		HTTPResponse response = request.GET(url)
		
		String url_2 = "http://127.0.0.1:8080/meeting/user/count"
		HTTPResponse response_2 = request.GET(url_2)

		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))
		}
	}
	
	// 06. 해당 모임 상세보기
	@Test
	public void test06() {
		String url = "http://127.0.0.1:8080/meeting/" + customMeetingId
		HTTPResponse response = request.GET(url)
		
		String url_2 = "http://127.0.0.1:8080/meeting/participants/" + customMeetingId
		HTTPResponse response_2 = request.GET(url_2)

		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))
		}
	}
	
	// 07. 모임 내 예약 추가
	@Test
	public void test07() {
		String url = "http://127.0.0.1:8080/meeting/" + customMeetingId + "/reservation"
		String body = "{\"description\" : \"description\" , \"date\" : \"3000-03-02T12:00\" , \"address\" : \"address\" , \"detailAddress\" : \"detailAddress\" , \"locateX\" : \"0\" , \"locateY\" : \"0\" , \"maxParticipants\" : 10}"
		
		HTTPResponse response = request.POST(url , body.getBytes())

		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))
		}
	}
	
	// 08. 모임 내 예약 참여
	@Test
	public void test08() {
		String url_01 = "http://127.0.0.1:8080/meeting/" + customMeetingId + "/reservation"
		HTTPResponse response_2 = request.GET(url_01)
		def jsonMsg = new JsonSlurper().parseText(response_2.getBodyText())
		customReservationId = jsonMsg.reservationId[0].toString()
		
		String url = "http://127.0.0.1:8080/meeting/reservation/" + customReservationId + "/join"
		String body = "{\"description\" : \"description\" , \"date\" : \"2000-03-02T12:00\" , \"address\" : \"address\" , \"detailAddress\" : \"detailAddress\" , \"locateX\" : \"0\" , \"locateY\" : \"0\" , \"maxParticipants\" : 10}"

		HTTPResponse response = request.POST(url)
		if (response.statusCode == 400 || response.statusCode == 302) {
			grinder.logger.warn("is already exist {}.", response.statusCode)
		} else {
			assertThat(response.statusCode, is(201))
		}
	}
	
	// 09 모임 내 예약 탈퇴
	@Test
	public void test09() {
		String url = "http://127.0.0.1:8080/meeting/reservation/" + customReservationId + "/leave"
		HTTPResponse response = request.DELETE(url)

		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))
		}
	}
	
	//10. 모임 수정
	@Test
	public void test10() {
		String url = "http://127.0.0.1:8080/meeting/" + customMeetingId
		def multipart = MultipartEntityBuilder.create()
                .addEntity("meeting", "{\"locateX\" : 30 , \"locateY\" : 30 , \"address\" : \"address22\" , \"title\" : \"title22\" , \"description\" : \"description22\" , \" detailAddress\" : \"detailAddress22\" , \"maxParticipants\" : 20}" , ContentType.APPLICATION_JSON)
				.addEntity("image", new File("./resources/test.png"))
                .build();
		HTTPResponse response = request.PUT(url , multipart)

		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))
		}
	}
	
	//11. 모임 탐색
	@Test
	public void test11() {
		String url = "http://127.0.0.1:8080/meeting/title-address?data=a"
		HTTPResponse response = request.GET(url)
		
		String url_2 = "http://127.0.0.1:8080/meeting/title-address?data=a"
		HTTPResponse response_2 = request.GET(url_2)

		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))
		}
	}
	
	//12. 모임 제거
	@Test
	public void test12() {
		String url = "http://127.0.0.1:8080/meeting/" + customMeetingId
		HTTPResponse response = request.DELETE(url)
		
		String url_2 = "http://127.0.0.1:8080/meeting/participants" + customMeetingId
		HTTPResponse response_2 = request.DELETE(url_2)

		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(204))
		}
	}
	
	class CommonData {
		public static final String userId = "tester"
		public static final String userEmail = "tester@naver.com"
		public static final String userPassword = "tester"
	}
	
}

시나리오 3 코드

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 org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith

import org.apache.hc.core5.http.ContentType
import groovy.json.JsonSlurper

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
import org.ngrinder.http.multipart.MultipartEntityBuilder

/**
* 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 test0
	public static GTest test1
	public static GTest test2
	public static GTest test3
	public static GTest test4
	
	public static HTTPRequest request = new HTTPRequest()
	public Map<String, String> headers = [:]
	public Map<String, Object> params = [:]
	public List<Cookie> cookies = []

	@BeforeProcess
	public static void beforeProcess() {
		HTTPRequestControl.setConnectionTimeout(300000)
		test0 = new GTest(0, "127.0.0.1")
		test1 = new GTest(1, "127.0.0.1")
		test2 = new GTest(2, "127.0.0.1")
		test3 = new GTest(3, "127.0.0.1")
		test4 = new GTest(4, "127.0.0.1")
		grinder.logger.info("before process.")
	}

	@BeforeThread
	public void beforeThread() {
		test0.record(this, "test00")
		test1.record(this, "test01")
		test2.record(this, "test02")
		test3.record(this, "test03")
		test4.record(this, "test04")
		grinder.statistics.delayReports = true
		grinder.logger.info("before thread.")
	}

	@Before
	public void before() {
		request.setHeaders(headers)
		CookieManager.addCookies(cookies)
		grinder.logger.info("before. init headers and cookies")
	}

	// 회원가입 -> 로그인 -> 마이 페이지 -> 개인 정보 변경 -> 재 로그인 -> 마이 페이지 -> 계정 탈퇴
	// 00. 회원가입
	@Test
	public void test00() {
		String url = "http://127.0.0.1:8080/registers";
		def multipart = MultipartEntityBuilder.create()
                .addEntity("data", "{\"id\": \""+CommonData.userId+"\" , \"email\": \"" + CommonData.userEmail + "\", \"password\": \""+CommonData.userPassword+"\" , \"checkPassword\" : \"" + CommonData.userPassword + "\"}" , ContentType.APPLICATION_JSON)
				.addEntity("image", new File("./resources/test.png"))
                .build();
				
		HTTPResponse response = request.POST(url, multipart)

		if (response.statusCode == 400) {
			grinder.logger.warn("is exist Account.", response.statusCode)
		} else {
			assertThat(response.statusCode, is(200))
		}
	}
	
	// 01. 로그인
	@Test
	public void test01() {
		String url = "http://127.0.0.1:8080/logins";
		String body = "{\"id\": \""+CommonData.userId+"\" , \"password\": \""+CommonData.userPassword+"\"}"
		grinder.logger.info(body);
		HTTPResponse response = request.POST(url, body.getBytes())

		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))
		}
		
		cookies = CookieManager.getCookies();
		CookieManager.addCookies(cookies)
	}
	
	// 02. 마이페이지
	@Test
	public void test02() {
		String url = "http://127.0.0.1:8080/profiles/statistics";
		HTTPResponse response = request.GET(url)
		
		String url_2 = "http://127.0.0.1:8080/profiles";
		HTTPResponse response_2 = request.GET(url_2)

		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))
		}
	}
	
	// 03. 개인 정보 변경 및 재 로그인
	@Test
	public void test03() {
		String url = "http://127.0.0.1:8080/profiles";
		String body = "{\"userId\": \"" + CommonData.changedId + "\", \"email\" : \"email@naver.com\" , \"phone\" : \"010123123123\" , \"options\" : 1}"
		HTTPResponse response = request.PUT(url, body.getBytes())

		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))
		}
		
		String url_2 = "http://127.0.0.1:8080/logins";
		String body_2 = "{\"id\": \""+CommonData.changedId+"\" , \"password\": \""+CommonData.userPassword+"\"}"
		HTTPResponse response_2 = request.POST(url_2, body_2.getBytes())
		
		cookies = CookieManager.getCookies();
		CookieManager.addCookies(cookies)
	}
	
	// 04. 계정 탈퇴
	@Test
	public void test04() {
		String url = "http://127.0.0.1:8080/users";
		HTTPResponse response = request.DELETE(url)

		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(204))
		}
	}
	
	class CommonData {
		public static final String userId = "nGrinderTest"
		public static final String changedId = "nGrinderNewId"
		public static final String userEmail = "nGrinderTest@naver.com"
		public static final String userPassword = "nGrinderTest"
		public static final int postId = 1
		public static String customPostId = "1";
	}
	
}

참고

참고 블로그 1 : https://0soo.tistory.com/223
참고 블로그 2 : https://thalals.tistory.com/288
참고 블로그 3 : https://leezzangmin.tistory.com/42

profile
https://github.com/5tr1ker

0개의 댓글