안녕하세요. SmartEditor BE 파트의 주니어 개발자 김일구입니다.
지난 블로그 글에서는 Postman과 Jenkins를 도입하게 된 이유, 그리고 적용 과정에서 마주한 문제에 대해서 소개해 드렸는데요, 그 이후 Postman 구성을 완료하고 몇 달간 사용해 본 후기를 들려드릴까 합니다. Postman을 사용해 보면서 좋았던 점과 아쉬웠던 점, 그리고 아쉬웠던 점을 일부 개선한 경험에 대해 소개하겠습니다.

Postman 도입하며 좋았던 점
1. 빠른 문제 원인 파악
Postman을 구성하고 나서 첫 번째 좋았던 점은 이전 글에서도 말씀드린 것처럼 SmartEditor의 여러 API에 대한 테스트를 간단하고 빠르게 실행해 볼 수 있다는 점이었습니다. SmartEditor 애플리케이션은 외부 API 연동이 많은데, 문제가 발생했을 때 원인이 SmartEditor API인지 외부 API로 인한 문제인지에 대한 빠른 확인이 필요합니다.

Postman에 SmartEditor API에 대한 테스트 스크립트를 저장해둔 이후로는 이전보다 빠르게 문제 원인 파악이 가능하게 되었습니다. 아래 그림에서처럼 어떤 테스트가 통과했고, 어떤 테스트가 실패했는지 한눈에 파악할 수 있는 점이 유용했습니다. API 응답에 대한 더 많은 테스트를 작성하면 문제 원인을 더 쉽게 파악할 수 있을 것이라 생각됩니다.

2. Postman API을 이용한 자동화 구성
Postman API는 Postman 계정에 저장된 데이터를 자유롭게 조회, 생성, 수정, 삭제할 수 있고, 이외에 다양한 기능도 제공하기 때문에 Jenkins를 이용한 자동화 구성을 하는데 꼭 필요한 기능입니다. 매달 Postman API 호출 횟수에는 제한이 있지만 적당히 조절할 수 있다면 유용하게 사용할 수 있습니다. 아래 예시는 Postman API를 이용하여 하나의 컬렉션의 모든 json 데이터를 가져오는 요청입니다.
curl -X GET https://api.getpostman.com/collections/$MY_COLLECTION_ID -H "X-Api-Key: $POSTMAN_API_KEY" -H "Cache-Control: no-cache" -o $OUTPUT_FILE
3. Jenkins와 연동을 통한 편리한 자동 테스트
Jenkins를 이용하면 특정 상황마다 트리거 되어 자동으로 코드가 빌드, 테스트, 배포되도록 할 수 있습니다. SmartEditor BE 파트에서는 Jenkins를 이용하여 매번 변경사항을 추가할 때나 정해진 시간마다 유닛 테스트, 정적 코드 분석, 슬랙 알림 기능이 작동하도록 구성하여 사용하고 있습니다. Postman 테스트도 Jenkins와 연동하여 자동으로 모든 API 테스트를 수행하고 슬랙 알람을 주도록 설정하였기 때문에 문제가 되는 부분을 놓치지 않고 파악할 수 있었습니다.

Postman 도입하며 아쉬웠던 점
1. Postman 데이터 추출 과정의 번거로움
Postman의 데이터는 회사 외부에 저장되기 때문에, 혹시 모를 데이터 유실을 방지하려면 따로 데이터 백업을 해두어야 했습니다. 다행히 Postman에는 아래 그림처럼 데이터를 json 형식으로 추출할 수 있는 기능을 제공하여 백업을 만드는 게 가능했습니다. 하지만 데이터 변화가 있을 때마다 json 파일을 추출해서 저장하고 관리하는 방식은 실수를 할 여지도 있고 반복작업이 되기 때문에 개선이 필요했습니다. 다행히 앞에서 소개해 드린 Postman API를 사용하면 자동 추출이 가능하여 이를 이용한 개선 과정은 아래에서 소개하겠습니다.

2. 조건부 테스트 스킵 기능의 부재
테스트를 운영하는 서버 환경 별로 구성하다 보면 서비스 운영 환경에서 데이터베이스의 변경이 발생하는 테스트는 실행되지 않도록 건너뛰어야 하는 상황이 종종 발생합니다. 하지만 Postman에는 pre-request script를 이용하여 특정 요청을 스킵 하는 기능이 없는 이슈가 있습니다 (Postman 공식 github 이슈). 이 때문에 테스트 전체 실행 시 스킵 해야 하는 테스트의 경우는 따로 개발 환경에서만 실행되도록 우회해야 했습니다. 이러한 테스트는 아래 그림과 같이 환경에 따라 변하지 않도록 Postman의 전역 변수를 추가하여 테스트하도록 했습니다.

3. 민감한 정보 저장 시 주의 필요
세 번째로 인증을 위한 키값이나 민감한 정보를 저장하지 않도록 주의해야 하는 점도 있습니다. Postman에 저장되는 데이터는 회사 외부에 위치하기 때문에 외부로 유출되면 안 되는 정보는 Postman에 저장하지 않도록 유의해야 할 필요가 있었습니다.
데이터 추출 반복작업 개선
Postman API 사용 횟수에는 제한이 있기 때문에 Jenkins를 이용하여 자동으로 테스트할 때마다 매번 Postman API를 사용하기 어려웠습니다. 따라서 Jenkins를 이용한 테스트 자동화를 위해 Postman 데이터를 새로운 저장소에 업로드해두고, Jenkins 서버가 이 저장소의 데이터를 가져와서 테스트를 진행하도록 구성하였습니다.

매일 아침 정해진 시간에 트리거 되면 위와 같이 Jenkinsfile에 기록한 여러 스테이지가 순차적으로 실행됩니다. 유닛 테스트와 Postman 테스트는 동시에 실행되도록 하였고, Postman 테스트는 먼저 Postman 데이터를 가져온 후 실행됩니다. 두 테스트에서 실패하는 테스트가 있을 때는 슬랙을 통해 알람을 받도록 설정되어 있습니다. 그 이후 소나큐브로 정적 코드 분석을 진행합니다.
이 과정에서 한 가지 불편한 점은 Postman 데이터 변경을 할 때마다 위의 그림에서처럼 수동으로 추출해야 하는 점이었습니다. 이를 덜 번거롭게 하기 위해 아래 그림처럼 Jenkins 웹 화면에서 ‘지금 빌드’ 버튼을 누를 때 Postman API 스크립트가 실행되도록 조건을 추가하여 데이터 추출 및 저장소 최신화가 쉽게 가능하도록 구성하였습니다.

위의 그림에서처럼 Jenkins 웹 화면에서 ‘지금 빌드’ 버튼을 클릭하면 트리거 되어 Jenkins 파이프라인의 여러 스테이지가 실행됩니다. 이때 한 스테이지에서 Postman API를 이용한 데이터 추출 스크립트가 실행되어 json 형식의 컬렉션 데이터, 환경 변수 데이터, 그리고 테스트용 파일을 추출합니다. 추출한 데이터를 기존 데이터와 비교하여 변경 사항이 생겼을 시 Postman 데이터 저장소에 업로드합니다.
Jenkins 파이프라인이 실행될 때 ‘지금 빌드’ 버튼 클릭으로 실행됐는지는 Jenkinsfile의 아래와 같은 함수를 통해서 확인할 수 있습니다. 이를 이용하면 Postman 데이터를 추출하고 github 저장소에 업로드하는 스테이지를 추가할 수 있습니다.
def isStartedByUser = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause').size()
if (isStartedByUser) {
stage('Export and Push Postman Data') {
ExportAndPushPostmanData()
}
}
평상시 테스트할 때는 Postman API를 사용하지 않도록 하였고 Postman 데이터 저장소 수정이 필요할 때만 사용하도록 하여 Postman API 사용을 최소화했습니다.
마치며
앞으로 출시될 Postman의 기능 중 하나인 Postman Flow는 아래 그림처럼 테스트 전 과정을 시각화할 수 있고 테스트를 실행할지 스킵 할지에 대한 조건을 추가할 수 있는 것으로 보여서 추후에 SmartEditor에 적용해 보고자 합니다. 이를 이용하면 앞에서 아쉬웠던 점으로 공유드렸던 조건부 테스트 스킵이 어려웠던 문제도 해결 가능할 것으로 보입니다.

Postman을 사용하면서 여러 가지 아쉬웠던 점도 있었지만, 빠른 테스트가 가능한 점과 팀 내에 동일한 테스트를 공유할 수 있다는 점, 보기 쉬운 UI 등 Postman만의 확실한 장점이 있기 때문에 API 테스트 및 모니터링에 있어서 좋은 도구로 사용할 수 있었고 앞으로도 많이 활용하고자 합니다.