테스트 구조 개선부터 시나리오 기반 테스트 자동화까지
안녕하세요. 회원/주문기획팀 서비스 기획자 김윤겸입니다.
지난 1편에서는 AI를 활용하여 반복적인 수동 테스트를 자동화한 경험을 소개해 드렸습니다. 테스트 데이터를 준비하고 API를 호출한 뒤, 응답 값을 기대 결과와 비교하는 코드를 구현하여 반복 테스트에 소요되는 시간을 획기적으로 단축할 수 있었습니다.
AI를 활용한 테스트 자동화 도전기 1편 보러가기
이번 2편에서는 테스트 자동화 확장 과정에서 발생한 한계를 극복하고, 시나리오 기반의 테스트 자동화 과정을 소개해 드리겠습니다.
테스트 자동화를 확장하면서 어떤 한계에 직면하였는가?
초기에는 테스트 케이스가 추가될 때마다 AI의 도움을 받아 필요한 코드를 개별적으로 작성하였습니다. 개별 테스트 코드를 빠르게 구현할 수 있었지만, 유지보수 측면에서 한계가 나타나기 시작하였습니다.
① 코드 중복 : DB 조회, API 호출, 응답 파싱 등 공통 기능 코드 중복 작성
② 코드 수정 : 공통 로직 변경 시 관련된 여러 파일의 코드 개별 수정테스트 자동화를 지속적으로 확장하기 위해서는 반복되는 기능을 공통 모듈로 분리하고 재사용할 수 있는 구조로 개선하는 것이 필요하였습니다.
반복되는 기능을 어떻게 공통 모듈로 분리하였는가?
테스트 대상과 검증 조건이 달라도 테스트에서 필요한 기능은 동일하였고, 여러 테스트 코드에서 반복적으로 사용하는 기능들을 정의하고 분류하였습니다.
① 파일 : 테스트 대상자 정보 읽기, 테스트 결과 저장
② API : API토큰 발급, API 요청, API응답 파싱
③ DB : 데이터 생성/변경/조회/삭제
④ 로그 : API요청/응답, SQL Query실행
⑤ 설정 : DB연결 설정 및 암호화 정보 관리위와 같이 분류된 공통 기능을 공통 모듈로 분리하고, 각 테스트 코드에서는 필요한 모듈을 Import하여 재사용할 수 있도록 구조를 개선하였습니다. 예를 들어, API 요청·응답 로그를 변경할 때 공통 모듈만 수정하면 해당 기능을 사용하는 모든 테스트 코드에 변경 사항을 일괄 적용할 수 있었습니다.
■ 예시1. API호출 공통화
def call_api(method: str, url: str, **kwargs):
logger.info("[API REQUEST] %s %s", method.upper(), url)
try:
response = httpx.request(
method, url, timeout=kwargs.pop("timeout", DEFAULT_TIMEOUT),
**kwargs
)
return response
except httpx.HTTPError as e:
logger.error("[ERROR] HTTP : %s", e)
return {
"status": "500",
"message": str(e)[:200],
"data": None,
}
finally:
time.sleep(DELAY_SECONDS)비즈니스 정책 유효성을 어떻게 검증하였는가?
이번 테스트 자동화의 목표는 ‘쓱7클럽 캐시백 정책’이 정상적으로 적용되는지 검증하는 것이었습니다. 캐시백 적립 여부를 정확하게 확인하려면 ‘최초 유료결제일’, ‘유료결제 후 해지 여부’, ‘캐시백 적립 횟수’ 등 다양한 조건 정보를 확인해야 했습니다.
① 유료 결제 후 해지 회원 제외② 유료결제월에 따라 캐시백 차등 지급
· ~26년 4월 : 3회
· ~26년 12월 : 2회
· 27년 1월 ~ : 0회(TBD)초기에는 쓱7클럽 가입 API 응답을 받은 후 정책 검증에 필요한 정보를 개별적으로 조회하였습니다. 여러 데이터를 조합하는 과정에서 검증 코드가 점차 복잡해졌습니다. 이를 개선하기 위해 API 응답 데이터와 DB 조회 결과를 하나의 DTO(Data Transfer Object)로 통합하였습니다.
쓱7클럽 가입 API 호출


