groovy 라는 언어를 모르니까 챗지피티랑 거의 3시간동안 씨름하면서 스크립트를 작성해달라고 해보았는데, 작성하는 족족 에러가 발생한다. validate 단계에서부터 끊임없는 오류발생.. 처음 nGrinder 사이트에서 만들었던 테스트코드는 오류가 발생하지 않았던걸 생각하면... 결국 테스트코드 내가 만들어내야 하나보다ㅠㅠ
이 두 분의 글을 참고하였다.
https://velog.io/@may_yun/Ngrinder-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9E%91%EC%84%B1
[Ngrinder] 스크립트 작성
스크립트 작성두가지 방법 존재Firefox 프록시 설정으로 TCPProxy Console 인터넷 액션을 수행하여 스크립트를 생성하는 방법(단 이방법은 Jython으로 생성되어 파악하기 힘들고, WAS만 테스트 하고 싶어
velog.io
https://hongjinkwon.tistory.com/63
2024-07-06 [nGrinder 성능 테스트]
성능테스트의 필요성대부분 해당 포스트를 읽는 분들은 성능 테스트의 필요성을 인지하고 있을 것이라 생각하지만... 그래도 필요성을 간략하게 설명하면애플리케이션이나 웹사이트에는 사용
hongjinkwon.tistory.com
일단 nGrinder 자체에서 script를 만들어보기로 한다.
nGrinder controller 에 접속해서 스크립트 만들기를 하면 이렇게 테스트 스크립트를 만들 수 있다.
여기서 우선 validate 버튼을 클릭하면 해당 스크립트를 우선 검증할 수 있다.
우선은 기본 아이디 한개로 로그인하는 테스트 코드를 만들어보려고 한다.
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.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
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 필수!
import org.apache.hc.core5.http.Header
import org.apache.hc.core5.http.message.BasicHeader
@RunWith(GrinderRunner)
class TestRunner {
public static GTest test
public static HTTPRequest request
public static byte[] requestBody
public static List<Header> headers
public static final String URL = "http://------/login"
@BeforeProcess
public static void beforeProcess() {
HTTPRequestControl.setConnectionTimeout(3000)
test = new GTest(1, "Login Test")
request = new HTTPRequest()
String json = '{
"userId":" == ",
"userPw":" ==== "
}'
requestBody = json.getBytes("UTF-8")
headers = [new BasicHeader("Content-Type", "application/json")]
}
@BeforeThread
public void beforeThread() {
test.record(this, "test")
grinder.statistics.delayReports = true
}
@Test
public void test() {
HTTPResponse response = request.POST(URL, requestBody, headers)
grinder.logger.info("응답 코드: ${response.statusCode}")
grinder.logger.info("응답 내용: ${response.getBodyText()}")
assertThat(response.statusCode, is(200))
}
}
결국 나와 가장 비슷한 상황으로 구글링을 해서 성공하신 분들의 코드를 직접 타이핑하면서 groovy 코드를 익히고, 내것에 맞게 바꾸어서 최종적으로 위와 같은 코드로 로그인에 성공했다.
응답코드 200, 성공적으로 로그인 했을때의 응답인 1이 반환되는 것을 볼 수 있다.
내가 접한 문제점 중에서는 로컬환경에서 spring 내장 tomcat으로는 docker에서 접근이 불가능하다는 문제가 있었다.
그래서 스프링을 외부 tomcat에 배포해서 실행해야 했고, 외장 포트에서 포트 0.0.0.0번에 대해서도 모두 오픈해주어야했다.
그리고 내가 모르는 언어를 챗지피티로 쓸 때 중요한 것은
내가 처한 환경을 계속해서 정확하게 얘기해주는 것인것같다.
"나는 순수 스프링을 사용하고 있다."
"내 API는 JSON 타입만을 받는다"
"현재 이러이러한 오류 로그가 뜬다"
이렇게 동시에 상황들을 알려주면 그제서야 제대로된 코드를 반환하는 것 같다.
이제 로그인 이후 상황을 실행해보아야 한다.
테스트 시나리오는 아래와 같다. 사실 시나리오라 할것도 없는 것이
사용자가 로그인하면 바로 투두리스트 페이지가 렌더링되는데, 이때 getTodo와 getMemo 메소드가 동시에 실행된다.
두 메소드 모두 todolist 열에 세션아이디와 날짜에 해당하는 행이 하나도 없으면 행을 입력하는 기능을 가지고 있기 때문에
여기에서 문제가 발생할 여지가 있다고 보아 테스트하는 것이다.
최종적으로 검증된 코드는 아래와 같다.
코드 검증에 꼬박 하루가 걸렸다.
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.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
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.apache.hc.core5.http.message.BasicHeader
// ✅ 여기에 이 두 개 import 필수!
import org.apache.hc.core5.http.Header
import org.apache.hc.core5.http.message.BasicHeader
@RunWith(GrinderRunner)
class TestRunner {
public static GTest test
public static HTTPRequest request
public static List<Header> headers // ✅ 여기도 Header로!
public static final List<List<String>> users = [
["가가", "1234"], ["감색", "1234"], ["네이비", "1234"], ["노랑", "1234"], ["드래곤스", "1234"],
["모카무스", "1234"], ["무명", "1234"], ["민아", "1234"], ["보라", "1234"], ["빨강", "1234"],
["슈붕", "1234"], ["스콧", "1234"], ["아이고", "1234"], ["연두", "1234"], ["주황", "1234"],
["지밍", "1234"], ["초록", "1234"], ["코이카", "1234"], ["팥붕", "1234"], ["핑크", "1234"]
]
public static final String BASE = "http://host.docker.internal:12345/planbee"
public static final String LoginUrl = "${BASE}/auth/login"
public static final String TodoList = "${BASE}/todolist/getTodo/250410"
public static final String Memo = "${BASE}/todolist/getMemo/250410"
String userId
public byte[] requestBody
@BeforeProcess
public static void beforeProcess() {
HTTPRequestControl.setConnectionTimeout(3000)
test = new GTest(1, "Login Test")
request = new HTTPRequest()
headers = [new BasicHeader("Content-Type", "application/json")]
}
@BeforeThread
public void beforeThread() {
int idx = grinder.threadNumber % users.size()
userId = users[idx][0]
String pw = users[idx][1]
String jsonBody = "{\"userId\":\"${userId}\",\"userPw\":\"${pw}\"}"
requestBody = jsonBody.getBytes("UTF-8")
test.record(this, "test")
grinder.logger.info("스레드 ${grinder.threadNumber} → 로그인 아이디: ${userId}")
}
@Test
public void test() {
HTTPResponse loginRes = request.POST(LoginUrl, requestBody, headers)
grinder.logger.info("응답 코드: ${loginRes.statusCode} (${userId})")
grinder.logger.info("응답 내용: ${loginRes.getBodyText()}")
assertThat(loginRes.statusCode, is(200))
HTTPResponse todoResponse = request.GET(TodoList)
grinder.logger.info("Todolist응답: ${todoResponse.statusCode} (${userId})")
grinder.logger.info("todo내용: ${todoResponse.getBodyText()}")
assertThat(todoResponse.statusCode, is(200))
HTTPResponse memoResponse = request.GET(Memo)
grinder.logger.info("memo응답: ${memoResponse.statusCode} (${userId})")
grinder.logger.info("memo내용: ${memoResponse.getBodyText()}")
assertThat(memoResponse.statusCode, is(200))
}
}
'SPRING' 카테고리의 다른 글
[Develop] 코드 수정 및 DTO 설계 수정 방안 (0) | 2025.04.11 |
---|---|
[Develop] nGrinder 드디어 부하테스트 시작 (0) | 2025.04.10 |
[Develop] nGrinder, Docker에서 실행하기 (0) | 2025.04.10 |
[Develop] HTTP와 HTTPS, 보안 강화하기 (0) | 2025.04.09 |
[Develop] 전역적 CORS 설정 안되었던 이유_Spring MVC (0) | 2025.04.09 |