최근에 ChatGPT가 소프트웨어 개발 영역에 많은 영향을 주고 있으며 소프트웨어 테스트분야도 예외는 아니다. ChatGPT가 테스트 영역에 어떻게 적용될 수 있는지에 대해 이제 부터 이야기 해 보려 한다.

ChatGPT가 영향을 줄 수 있는 테스트 활동은 다음과 같다(Dr Stuart Reid의 동영상강의 참고)

  • 테스트 아이디어 도출
  • 요구사항 리뷰
  • 테스팅 가이드
  • 코딩(테스트 스크립팅)
  • 테스트 결과 분석
  • 인수 테스트(예;cucumber)
  • 테스트 데이터 생성
  • 탐색적 테스팅 지원

테스트 아이디어 도출

어떤 시스템을 처음 봤을 때에 어떻게, 무엇을 테스트해야 할 지 막연한 경우가 많다. 이런 경우 ChatGPT의 지원을 받아 테스트의 방향을 잡을 수 있다.

예를 들어 학교 홈페이지를 테스트할 때 어떻게 테스트를 해야 할 지 문의를 해 보았다.

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515001708611

기능 테스트 및 사용성 테스트, 호환성 테스트, 보안, 부하 테스트 까지 다양한 관점의 테스트를 제안하고 있다.

요구사항 리뷰

리뷰의 의미는 기존의 요구사항에 부족함이나 잘못이 없느냐를 검증하는 활동이다. 이미 작성한 요구사항이 있다고 가정하고 이를 검토를 받고 부족한 것은 없는지 물어보도록 하자.

전자 상거래(쿠팡 등)의 요구사항을 아래와 같이 도출했다고 가정하자

  • 서비스 이용을 위해 회원가입 및 로그인한다.
  • 원하는 상품을 빠르게 고르기 위해 홈 화면에서 사용자에게 맞는 상품들을 추천해준다.
  • 원하는 상품을 빠르게 찾기 위해 카테고리를 살펴보고, 원하는 카테고리를 선택한다. 원하는 상품을 빠르게 찾기 위해 상품 키워드를 검색한다.
  • 상품의 평가를 확인한다.
  • 판매자에게 궁금한 점을 문의한다.
  • 마음에 드는 상품을 장바구니에 담는다.
  • 구매하기 버튼을 클릭한다.
  • 주문 상태를 확인하고 배송 조회를 한다.

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515094815263

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515094853301

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515094944653

기존의 사항들은 문제가 없다고 판별하는 것 같다. 여기에 부족한 부분이 있는지 물어본다.

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515095217758

나름대로 요구사항의 평가 및 보충을 훌륭하게 해 주는 것 같다.

테스팅 가이드

테스팅 가이드라고 하면 여러가지 의미가 있는데 보통 아래의 것들을 포함한다.

  1. 테스트 범위
  2. 테스트 방법론
  3. 테스트 케이스 설계
  4. 테스트 환경
  5. 테스트 실행
  6. 테스트 리포팅
  7. 테스트 수행시 역할과 책임

여기서 ‘3. 테스트 케이스 설계’부분에 대해 도움을 받아보도록 하겠다.

‘설계’ 라고 하면 상황별 테스트 기법에 얽메이는 경우가 가끔 있는데 여기에서 ‘설계’의 의미는 ‘제작’의 의미로 보면 될 것 같다. 우리의 목적은 케이스를 잘 만드는 것이지 최적의 기법을 적용하는게 아니기 때문이다.

아래 코드를 가지고 테스트 케이스를 만들어 달라고 해 보겠다. (테스트 설계 기법 중 구조적 기법에 해당될 것이다)

대상 코드…

package com.example.sjkim;
import java.io.FileReader;
...
import org.springframework.core.io.ClassPathResource;
@SpringBootApplication
public class SjkimApplication {
	public static void main(String[] args){
		SpringApplication.run(SjkimApplication.class, args);
	}
	public Integer ApplicationTest(String id, String pw) {
		JSONParser parser = new JSONParser();
		try{
			//사용자 정보 가져오기
			Resource resource = new ClassPathResource("User.txt");
			//InputStream input = resource.getInputStream();
			File file = resource.getFile();
			FileReader reader = new FileReader(file);
			JSONObject jsonObject = (JSONObject) parser.parse(reader);
			reader.close();
			////////////////////
			boolean isIdExist = jsonObject.containsKey(id);
			JSONObject userObj = (JSONObject)jsonObject.get(id);
			//id, pw미입력
			if (id.length() == 0){
				return globalVar.FIRST_CASE;
			}
			if (pw.length() ==0){
				return globalVar.FOURTH_CASE;
			}
			if (isIdExist)
			{
				//HAPPY CASE
				if (pw.equals(userObj.get("pw"))){
					return globalVar.HAPPY_CASE;
				}
				else{
					//PW불일치
					return globalVar.SECOND_CASE;
				}
			}
			else{
				//ID가 존재하지 않음
				return globalVar.THIRD_CASE;
			}			
		}catch(Exception e ){
			e.printStackTrace();
			return globalVar.UNKNOWN_CASE;
		}
	}
}

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515135206583

@Test
public void testHappyPath() {
    SjkimApplication app = new SjkimApplication();
    Integer result = app.ApplicationTest("valid_id", "valid_pw");
    assertEquals(globalVar.HAPPY_CASE, result);
}

@Test
public void testInvalidPassword() {
    SjkimApplication app = new SjkimApplication();
    Integer result = app.ApplicationTest("valid_id", "invalid_pw");
    assertEquals(globalVar.SECOND_CASE, result);
}

@Test
public void testNonExistentId() {
    SjkimApplication app = new SjkimApplication();
    Integer result = app.ApplicationTest("non_existent_id", "any_pw");
    assertEquals(globalVar.THIRD_CASE, result);
}

@Test
public void testEmptyId() {
    SjkimApplication app = new SjkimApplication();
    Integer result = app.ApplicationTest("", "any_pw");
    assertEquals(globalVar.FIRST_CASE, result);
}

@Test
public void testEmptyPassword() {
    SjkimApplication app = new SjkimApplication();
    Integer result = app.ApplicationTest("valid_id", "");
    assertEquals(globalVar.FOURTH_CASE, result);
}

@Test
public void testFileNotFound() {
    SjkimApplication app = new SjkimApplication();
    // 여기서 User.txt 파일을 찾을 수 없거나 읽을 수 없는 상황을 시뮬레이션해야 합니다.
    // 이를 위해 Mocking 기술을 사용할 수 있습니다.
}

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515135349840

@Test
public void testFileNotFound() {
    SjkimApplication app = new SjkimApplication();

    // Mocking을 위한 준비
    ClassPathResource mockResource = Mockito.mock(ClassPathResource.class);
    Mockito.when(mockResource.getFile()).thenThrow(new IOException());

    // 에러를 던지는 Mocked resource를 사용해 테스트 수행
    Integer result = app.ApplicationTest("any_id", "any_pw", mockResource);
    assertEquals(globalVar.UNKNOWN_CASE, result);
}

사실 마지막 모킹을 사용하는 부분은 User.txt 파일의 존재 여부 테스트 부분이므로 필요는 없다. 생각보다 테스트는 잘 뽑아내는 것 같다.

이렇게 구조기반 베이시스로 테스트 케이스를 뽑아내는 것은 chatGPT가 상당히 정확하다. 정보가 정확하기 때문이다.

명세 기반 베이시스 테스트 케이스를 만드는 것은 결과에 대한 검토가 필요하다.

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515153027211

케이스는 이렇게 만들어 줬지만(심지어 경계값 케이스도 만들어주었다), 이 케이스들이 여러분들의 시스템 상황에 가능한 것들인지는 직접 체크하면서 뺄 것은 빼야 한다.

코딩(테스트 스크립팅) + 인수 테스팅

테스트 스크립트도 만들어 준다 예를 들어 cucumber + behave로 만들어 보면…

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230515235106356

걸킨 언어로 나름 잘 만들어 준다. 테스트 코드까지 부탁해 보자.

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230516000233725

테스트 결과 분석

테스트 결과의 데이터를 ChatGPT에 넘기는 것은 좀 위험해 보인다. 공개에 민감한 결과가 있을 수 있기 때문이다. 다만 분석 방법에 대해서는 조언을 얻을 수 있다. 예를 들어 A/B테스트의 분석 과정의 조언이다.

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230516130354311

테스트 데이터 생성

앞에서의 ID/PW 케이스를 가지고 테스트 데이터르 만들어 달라고 해 보자..

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230516133812862

잘 만들어 주었다.

탐색적 테스트 지원

탐색적 테스트를 하는 사람들이 주위에는 거의 없어 이를 실험해 보는게 쉽지는 않았다. 그래서 ChatGPT에게 거꾸로 물어보았다.

https://raw.githubusercontent.com/cheuora/cheuora.github.io/master/_posts/2023/images/image-20230516141241352

테스트 계획 도움, 테스트 데이터 생성에 대해서는 앞에서 언급한 것들과 중복이 되나, 결과 분석(테스트 로그 분석, 문제 분석), 리포트 작성(결과요약, 문제점 문서화) 에 도움을 줄 수 있다고 말하고 있다.

결론..

100%는 아니지만 많은 도움을 테스트 진행시에도 얻을 수 있다. 다만 100%얻기 어려운 부분은 테스트 결과 분석, 탐색적 테스트 등이며 이 분야에서는 부분적으로 도움을 받을 수 있을 것 같다.

GPT가 테스터를 대체할 수 있을까에 대한 문제는 아마 GPT가 개발자를 대체힐 수 있을까의 문제와 유사한 것 같다. 세부적인 사항들은 도움을 받을 수 있을지 모르겠지만, 이에 대한 상황에 맞는 방향성 판단은 여전히 사람이 필요하다.