이번 글에서는 필자가 회사에서 구성한 Newman API 테스트 프로세스에 대해 설명하려 한다.
Newman이란 간단하게 Postman의 CLI 버전이다.
NPM을 통해 설치할 수 있고, 사실 Postman도 CLI가 따로 존재하기는 한다.
둘 다 포스트맨에서 개발하였으며, Newman은 오픈 소스로 공개해 커뮤니티 기여로 지원하고 있고 Postman-CLI는 포스트맨 자체에서 유지/보수한다고 한다.
둘의 차이는 포스트맨 공식 문서에 존재한다.
필자가 사용해봤을 때, 둘 다 유의미한 차이가 존재하지는 않고 Newman의 경우 테스트 결과를 HTML 리포트 형식으로 받을 수 있는 패키지와 Slack 알림 기능 패키지를 NPM을 통해 쉽게 받을 수 있어 Newman을 사용하기로 정하였다.
Newman의 설치 방법은 NPM이 설치된 상태에서 아래 명령어를 입력한다.
npm install -g newman
그리고 테스트 결과를 HTML 리포트로 생성하여 슬랙 알림으로 받을 수 있게끔 아래의 패키지도 같이 설치한다.
npm install -g newman-reporter-htmlextra newman-reporter-slackmsg
Newman의 사용법은 아주 간단하다.
먼저 Postman으로 테스트 케이스를 작성하고, 테스트의 성공 조건을 작성해준다.
필자는 Response의 Code가 200(성공)이면, 해당 테스트 케이스는 성공이라고 작성하였으며, 자신이 원하는 다른 방식으로 작성해도 상관없다.

그리고 해당 콜렉션을 Json으로 Export 하거나 Share로 접근할 수 있는 URL를 만들어준다.
필자는 Postman API 키를 생성해 URL를 만드는 방식을 택했다.


그리고 아래의 명령어로 실행하면 해당 콜렉션에 있는 요청들로 테스트가 진행된다.
newman run <COLLECTION_URL>
이제 Newman 테스트를 Github Actions을 통해 자동화해보자.
워크플로우 파일을 아래와 같이 작성했다.
name: API Test Script
on: workflow_dispatch
jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
java-version: 17
distribution: "oracle"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- run: chmod +x ./gradlew
- run: nohup sudo ./gradlew bootrun --args='--spring.profiles.active=test' > ./log.txt &
- run: sleep 20s
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g newman newman-reporter-htmlextra newman-reporter-slackmsg
- run: newman run ${{ secrets.POSTMAN_API_TEST_URL }} -r htmlextra,slackmsg --reporter-htmlextra-export report.html --reporter-slackmsg-webhookurl ${{ secrets.SLACK_WEBHOOK_URL_TO_ALERT_CHANNEL }}
필자의 회사에서는 애플리케이션을 Spring Boot로 개발하기 때문에 JAVA와 Gradle을 Setup 해준 뒤 빌드를 진행하고, 빌드가 성공하면 그 워크플로우 머신에서 서버를 실행시킨다.
그 후 Newman 패키지를 설치해 localhost로 테스트 케이스를 작성한 뒤 실행하면 끝이다.
참고로 중요 정보는 Secret으로 저장해 액션내에서는 ${{ secrets.<SECRET_NAME> }}으로 사용해야 한다.
여기에는 두 가지 문제점이 있다.
1) 이 워크플로우 내에서 Spring Boot 애플리케이션이 연결될 데이터베이스는 어디에 있는가?
2) 테스트가 종료된 이후 쌓인 데이터를 어떻게 클렌징해줄 것인가?
외부 데이터베이스를 연결하려면, 해당 데이터베이스 서버가 존재하는 네트워크에서 방화벽으로 Github Actions Runner의 IP를 허용해주어야 하지만 Github Actions의 Runner의 IP 대역은 찾아보니 방화벽에 추가하는 것이 말이 안될 정도로 많다.
그렇다고 방화벽을 아예 오픈하는 것은 더더욱 말이 안될 것이다.
또 GET 요청만 테스트하는 경우에는 상관이 없을 수도 있는데 PUT,POST 등 데이터베이스에 데이터의 삽입과 변경이 행해지는 테스트가 종료된 이후에는 다시 원래 상태의 데이터베이스로 어떻게 돌릴지가 문제다.
필자는 위 두 문제를 Github Actions의 Service 컨테이너로 해결해보았다.
Github Actions에는 워크플로우 내에서 통신할 수 있는 서비스 컨테이너라는 것을 만들 수 있다.
이 서비스 컨테이너는 해당 Job이 처음 생성될 때 같이 생성되고 Job이 종료될 때 같이 종료된다.
즉, 테스트에 필요한 데이터를 미리 삽입해놓은 데이터베이스 컨테이너 이미지를 생성해두고 이를 워크플로우 내에서 실행시킨 뒤, 테스트가 끝나면 종료되기 때문에 클렌징이 필요하지 않다.
또, 방화벽을 오픈할 필요없이 동일한 워크플로우 머신 내에서 컨테이너가 실행되는 것이기 때문에
위 두 문제를 해결할 수 있다.
Dockerfile로 테스트에 필요한 초기 데이터를 갖고 있는 데이터베이스 컨테이너 이미지를 생성한다.(이는 테스트를 위해 필요한 초기 데이터가 없다면 필요없는 과정이다.)
FROM postgres:15.6
추후 추가 예정..
그리고 컨테이너 이미지를 만들어 이미지 저장소에 푸시한다.
docker build -t <CONTAINER_IMAGE_REGISTRY>/REPO:TAG .
docker push <CONTAINER_IMAGE_REGISTRY>/REPO:TAG
이 후 워크플로우 파일로 돌아가 해당 컨테이너를 실행하게끔 설정해준다.
name: API Test Script
on: workflow_dispatch
jobs:
-- 이 부분 추가
services:
postgres:
image: <CONTAINER_IMAGE_REGISTRY>/REPO:TAG
credentials:
username: _json_key
password: ${{ secrets.GOOGLE_ARTIFACT_REGISTRY_CREDENTIALS }}
ports:
- 5432:5432
env:
POSTGRES_PASSWORD: postgres
--
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Setup Java
uses: actions/setup-java@v4
with:
java-version: 17
distribution: "oracle"
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- run: chmod +x ./gradlew
- run: nohup sudo ./gradlew bootrun --args='--spring.profiles.active=test' > ./log.txt &
- run: sleep 20s
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install -g newman newman-reporter-htmlextra newman-reporter-slackmsg
- run: newman run ${{ secrets.POSTMAN_API_TEST_URL }} -r htmlextra,slackmsg --reporter-htmlextra-export report.html --reporter-slackmsg-webhookurl ${{ secrets.SLACK_WEBHOOK_URL_TO_ALERT_CHANNEL }}
- uses: MeilCli/slack-upload-file@v4
with:
slack_token: ${{ secrets.SLACK_TOKEN_NEWMAN }}
channel_id: ${{ secrets.SLACK_ALERT_CHANNEL_ID }}
file_path: 'report.html'
if: always()
- uses: MeilCli/slack-upload-file@v4
with:
slack_token: ${{ secrets.SLACK_TOKEN_NEWMAN }}
channel_id: ${{ secrets.SLACK_ALERT_CHANNEL_ID }}
file_path: 'log.txt'
if: failure()
필자는 Google Cloud Platform에 있는 컨테이너 레지스트리 Artifact Registry에 저장해 사용하는 형태라 관련 인증정보가 필요해 추가된 상태이다.
그리고 Spring Boot에서 Test Profile을 만들어 localhost:5432로 연결하게끔 실행해주면 Newman 테스트를 성공할 수 있다.
테스트가 종료되면 결과가 슬랙 채널로 올라오게 되고, 필자는 HTML 리포트 파일을 슬랙 채널에 업로드하는 액션을 추가로 사용하여 아래와 같이 알림을 주게 된다.

그리고 실패 시에는 애플리케이션 로그 파일을 함께 업로드한다.

오늘은 필자가 회사에서 구성한 테스트 자동화 프로세스를 구성했던 방법을 설명해보았다.
슬랙 웹 훅 등 아직 글을 전부 작성한 것은 아니라 보완해야 할 점은 추가로 보완해나갈 것이다.