포트폴리오를 약 750명의 커뮤니티에 공개하기 전 부하 테스트를 해보기로 했다. 현재 서버가 1vCPU 1GB RAM의 낮은 스펙이라서 사용자가 집중될 경우 서버가 다운될 우려가 있기 때문이었다.
앞선 두 번의 테스트 결과 사람들은 게시판을 눌러보며 탐색해보고, 회원가입 보다는 테스트 계정을 사용했으며, 글 작성보다는 댓글 작성이나 수정 등 변경 사항이 잘 보이지 않는 기능을 테스트 해보는 경우가 많았다.
따라서 (1) 홈 접근 -> (2) 테스트 계정 로그인 -> (3) 4개의 게시판 탐색 -> (4) 게시글 클릭 -> (5) 댓글 수정이라는 시나리오를 가지고 테스트를 해 보았다.
게시글 수정의 경우 로그인 세션이 필요하기 때문에 다음과 같이 스크립트를 작성했다.
@RunWith(GrinderRunner)
class TestRunner {
public static GTest test
public static HTTPRequest request
public static Map<String, String> headers = [:]
public static Map<String, Object> params = [:]
public static List<Cookie> cookies = []
@BeforeProcess
public static void beforeProcess() {
HTTPRequestControl.setConnectionTimeout(300000)
test = new GTest(1, "scenario1")
request = new HTTPRequest()
// Set header data
headers.put("Content-Type", "application/x-www-form-urlencoded")
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)
CookieManager.addCookies(cookies)
grinder.logger.info("before. init headers and cookies")
}
@Test
public void test() {
HTTPResponse response1 = request.GET("https://www.bangcom.store/")
checkStatusCode(response1, 200)
HTTPResponse response2 = request.POST("https://www.bangcom.store/login", ["loginName":"user","password":"password123!"])
checkStatusCode(response2, 302)
HTTPResponse response3 = request.GET("https://www.bangcom.store/info")
checkStatusCode(response3, 200)
HTTPResponse response4 = request.GET("https://www.bangcom.store/community")
checkStatusCode(response4, 200)
HTTPResponse response5 = request.GET("https://www.bangcom.store/notice")
checkStatusCode(response5, 200)
HTTPResponse response6 = request.GET("https://www.bangcom.store/questions")
checkStatusCode(response6, 200)
HTTPResponse response7 = request.PUT("https://www.bangcom.store/api/v1/articles/comments/29", ["commentId":"29","content":"edited!"])
checkStatusCode(response7, 200)
}
private void checkStatusCode(HTTPResponse response, int expectedStatus) {
assertThat(response.statusCode, is(expectedStatus))
}
}
이 스크립트의 핵심은 로그인 세션을 유지하는 것인데, @Test
하나에 하나의 시나리오 요청을 모두 넣어주면 된다.
checkStatusCode()
는 응답 코드가 기대한 결과와 일치하는지 검사하는 assertThat
코드인데 반복되기 때문에 별도로 뺐다. 로그인은 성공한 경우 리다이렉트되기 때문에 기대값은 302
이다.
payload
는 ["key1":"value1", "key2":"value2"]
와 같은 형태로 보낼 수 있다. GET
, POST
, PUT
모두 사용방법이 동일하다. (레거시의 경우 각각 NVPair
객체를 만들어주어야 한다.)