brunch

You can make anything
by writing

C.S.Lewis

by 이지원 May 13. 2023

Don't reinvent the wheel

테스트 자동화 에세이

API 테스트는 CICD 파이프라인에서 UI 테스트 자동화와 상호보완 형태로 사용하면 효율적이다. API 테스트가 강점을 보이는 상황은 화면단보단 데이터가 중요한 E2E 시나리오이다. 잦은 UI 변경에 대한 대처와 더불어 UI와 함께 API 테스트 자동화를 병행할 경우 QA팀의 리그레션 테스트 시간을 절약할 수 있다. API 테스트를 QA팀에서 리그레션 형태로 커버리지를 관리해야 하는 이유는 UI 테스트와 병행했을 때의 효과가 뛰어나기 때문이다. UI 테스트, 즉 E2E 테스트 레이어는 일반적으로 개발팀이 아닌 QA팀이 수행하는 경우가 많기 때문에, QA팀 관점에서 필요한 API 테스트 시나리오를 설계하고 수행하는 것이 효과적이다.


내가 생각하는 API 테스트의 목표는 단순히 상태코드만 체크하는 것이 아니라 정상 동작 시에 응답과 데이터가 적절한지에 대한 체크도 함께 포함하는 것이다. API 테스트 또한 기능 테스트이기 때문에 상태코드가 200일지라도 데이터가 정말 정상적인 데이터인지에 대한 의심과 검증이 필요하다. QA는 직군 특성상 늘 의심하고 경계해야 한다. 개발자 관점에서는 상태코드 200이면 문제가 없다고 생각할 순 있겠지만 소프트웨어 품질을 책임지는 직군에서는 다양한 상황에 대해 대비하고 예방해야 한다.

CICD 파이프라인에서 모든 테스트 계층(Web Mobile API DB..)을 단일 프레임워크와 1가지 언어로 운영하는 게 유지보수와 운영면에서 좋겠어, QA팀 리소스는 언제 어디서나 늘 제한적이기 때문이고, 여러 도구를 활용하는 것보단 하나의 도구를 깊게 활용하는 것이 좋겠어.

API 기능 테스트 자동화는 간편하고 접근이 쉬운 Postman을 활용한 방식을 선호했었지만 위와 같은 고민 끝에 단일 프레임워크에서 모든 테스트 계층을 관리하고자 SuperTest 라이브러리를 살펴보게 되었다.


https://github.com/ladjs/supertest

The motivation with this module is to provide a high-level abstraction for testing HTTP, while still allowing you to drop down to the lower-level API provided by superagent.
POST 요청 예시 코드

적지 않은 사용자가 사용 중이었고 무엇보다 Python의 request 만큼이나 구현 과정이 깔끔했다. 따라서 Postman을 활용하지 않고 SuperTest 라이브러리를 기반으로 API 테스트 자동화를 구축하기 시작했다.

UI 테스트와 마찬가지로 재사용성이 중요해. QA팀이 API 테스트에 대한 최신 API 스펙을 별도로 유지하고 관리하기 위해선 그만큼 운영과 구현에 필요한 비용을 최소화해야 해. GET POST DELETE 요청에 대해 재사용 가능한 함수를 만들어야겠어. 아무래도 GET POST DELETE 요청을 1개의 함수로 구현하는 것보단 각각의 요청에 대한 개별 함수로 분리하는 게 좋을 것 같아.

baseUri와 payload, endpoint가 필요하겠구나, 이것들을 별도로 관리해서 GET POST DELETE 요청에 대한 함수를 어떠한 시나리오든 재사용할 수 있게 만드는 게 좋겠어. 비유효 시나리오에 대한 payload에서는 faker 라이브러리를 활용해도 괜찮을 것 같네.

API 기능 테스트 플로우도 살펴볼 겸 API 테스트 자동화 구현에 필요한 정보들을 하나하나 직접 확인해 보는 게 좋겠어. 우선 유효 이메일과 비밀번호로 로그인을 시도했을 때 로그인 API가 어떤 API인지 살펴보자. 헤더와 페이로드 그리고 응답이 이렇게 오는구나, 이런 식으로 서비스에 중요한 API를 하나씩 살펴보고 필요한 payload와 endpoint를 정리하면 좋을 것 같아. 검증은 statusCode와 Token의 유무 그리고 비유효시나리오일 경우 에러에 대한 body 체크를 모두 해야겠어.

이제 거의 끝났네, CICD 파이프라인에서 실행할 스크립트를 package.json에 추가하고 unit 테스트 이후 e2e 테스트 실행 스크립트 전에 실행되도록 구성해야겠어. 어차피 api 테스트는 실행 속도가 굉장히 빠르니 ci 워크플로우 job을 분리하지 않아도 될 것 같아.
기술 블로그용 데이터

재사용 가능한 구조로 진행하니 Postman을 활용하지 않아도 앞으로 추가되는 API 테스트 구현과 결과 검증이 편리해졌다. endpoint와 payloads만 관리한다면 API 기능 테스트 영역은 쉽게 유지관리 가능한 구조였기 때문에 만족스러웠다.

https://www.npmjs.com/package/mochawesome

리포트는 Mochawesome 리포트를 사용했다. WebdriverIO를 Mocha 기반으로 진행할 경우에도 많이 활용하는 리포트 라이브러리 중 하나이다.

시간이 흘러..

올해 1월, 테스트 자동화 분야의 셀레니움 생태계에서 엄청난 발표가 있었다. 테스트 자동화 프레임워크를 개발하는 소프트웨어 개발자가 만든 Java-Maven-Intellij 기반의 통합 테스트 자동화 엔진이, 셀레니움 생태계의 구성원이 된 것이다. 셀레니움 생태계의 구성원이 된다는 것은 해당 엔진이 Selenium WebDriver 위에 구축되고 공식적으로 생태계에 합류한 13개의 고수준 프레임워크 중 하나라는 것을 의미한다. 이에 따라 앞으로 더 많은 커뮤니티 지원을 얻을 것으로 예상되고 Java 기반이기 때문에 글로벌 SDET들의 지원과 활용이 예상되었다. 또한 해당 엔진을 개발한 핵심 관리자는 계속해서 Selenium Technical Leadership 위원회와 긴밀한 관계를 유지하여 항상 최신 Selenium WebDriver가 제공하는 것과 일치하도록 밤낮으로 지원하고 있었다.


올해 1월 이러한 소식 발표 이후 매 주말마다 해당 동향을 지속적으로 살펴보았고 셀레니움 생태계의 구성원이 된 통합 테스트 엔진에서 API 테스트 자동화가 RestAssured 기반으로 Builder, Parsing, Validations 개념으로 구현되어, 정말 간편하게 사용할 수 있는 점을 알게 되었다.

API 테스트 샘플 코드

간결하고 또 간결하다는 것 외엔 다른 생각이 떠오르지 않았다.

String body 대신 Hash로 위와 같이 구현할 수도 있었다. 타입스크립트로 구현한 SuperTest 라이브러리 기반의 API 테스트 구축 과정이 떠올랐고 많은 생각에 잠겼다.


내가 아직 품질 엔지니어로서 부족한 부분들은 이러한 점들이다. 이미 잘 만들어진 바퀴가 존재함에도 불구하고 직접 무언가를 해보려는 시도. 물론 위 사례에서 등장했던 통합 테스트 엔진에 대해 테스트 환경과 지속 가능한 운영의 관점에서 내부 구현을 살펴보다 우연히 알게 된 API 테스트 구현의 편리함이었고, 만약 Java 기반의 통합 테스트 엔진이 필요치 않다면 WebdriverIO와 SuperTest로 진행되는 테스트 환경의 관점에서 지금과 같이 재사용 가능한 GET POST DELETE 함수를 살펴보는 것은 나쁘지 않은 과정이었다. 약간의 시간만 투자하면 앞으로의 과정이 편리해지기 때문이다.


엔지니어로서 개인시간에는 현재 사용하는 기술에 대한 학습을 이어가는 것도 좋지만, 내가 속한 테스트 자동화 분야에 다양한 접근 방식에 의해 설계된 프레임워크를 많이 살펴보는 것도 현재 사용하는 기술에 대한 깊이 만큼이나 중요한 자질 아닐까, 오늘도 과거의 나로부터 배웠고 깨달음을 얻게 된 시간이었다.


Don't reinvent the wheel, 이미 만들어진 바퀴를 다시 발명하지 않는 품질 엔지니어가 될 수 있도록 노력함과 동시에 바퀴에 대한 이해가 있어야 수레에서 자동차까지 만들 수 있다는 관점을 지닌 채 앞으로도 과거의 나로부터 많은 배움과 깨달음을 얻게 되는 시간이 쌓이고 쌓여 테스트 자동화 분야에서 목표로 한 지점까지 도달했으면 하는 바람이다.

매거진의 이전글 우리만의 지식과 전문성

작품 선택

키워드 선택 0 / 3 0

댓글여부

afliean
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari