인수 테스트(User Acceptance Testing, UAT)란 소프트웨어가 요구사항 명세대로 구현되었는지 최종적으로 확인하는 과정이다. 이는 개발의 마지막 단계에서 비즈니스 요구사항을 충족하는지 검증하는 절차로, 제품의 출시 여부를 결정하는 핵심 단계이다.
그러나 UAT의 자동화는 다음과 같은 이유로 난이도가 높다.
- 사용자 참여: 실제 사용자의 행위를 모방해야 하므로 시나리오가 복잡하다.
- 환경의 일치성: 개발, 스테이징, 프로덕션 환경이 미세하게 다를 경우 테스트 신뢰도가 하락한다.
- 릴리스 준비: 애플리케이션의 버전 관리와 배포 준비 과정이 선행되어야 한다.
이러한 문제를 해결하기 위해서는 동일한 바이너리(아티팩트)가 파이프라인의 모든 단계에서 사용됨을 보장해야 하며, 이를 위해 아티팩트 리포지토리와 컨테이너 기술(Docker)의 도입이 필수적이다.
1. 아티팩트 리포지토리와 도커 레지스트리
1.1 아티팩트 리포지토리 (Artifact Repository)
아티팩트 리포지토리는 소프트웨어 개발 산출물(바이너리, 라이브러리 등)을 버전 관리하고 접근을 제어하는 저장소이다. 지속적 인도(Continuous Delivery) 프로세스에서 빌드된 결과물을 저장하고, 이후 단계(테스트, 배포)에서 이를 인출하여 사용함으로써 '빌드는 한 번만, 배포는 여러 곳에'라는 원칙을 지킬 수 있게 한다.
1.2 도커 레지스트리 (Docker Registry)
도커 레지스트리는 컨테이너화된 소프트웨어의 산출물인 도커 이미지를 저장하고 관리하는 특수한 형태의 아티팩트 리포지토리이다.
- 클라우드 호스팅 방식: Docker Hub, AWS ECR, GCP Artifact Registry 등 유지보수가 편리하다.
- 자체 호스팅(Self-Hosted) 방식: 폐쇄망 정책이나 보안상의 이유로 사내 네트워크에 직접 구축하는 방식이다. 관리에 대한 부담이 있으나 데이터 주권과 보안성이 높다.
1.3 로컬 도커 레지스트리 실습
Docker Hub의 공식 registry 이미지를 사용하여 로컬 환경에서 사설 레지스트리를 구축하고 테스트하는 과정은 다음과 같다.
# 1. 레지스트리 컨테이너 실행 (포트 5000)
docker run -d --rm -p 8765:5000 --name registry registry:2
# 2. 이미지 태깅 및 로컬 레지스트리로 푸시
docker tag ubuntu:22.04 localhost:8765/ubuntu:22.04
docker push localhost:8765/ubuntu:22.04
# 3. API를 통한 등록 확인
# 카탈로그 확인: {"repositories":["ubuntu"]}
curl localhost:8765/v2/_catalog
# 태그 확인: {"name":"ubuntu","tags":["22.04"]}
curl localhost:8765/v2/ubuntu/tags/list
2. Kubernetes(k8s) 환경에서의 레지스트리 구축
단일 도커 컨테이너를 넘어, Kubernetes 클러스터 내에서 레지스트리를 운영하기 위해 Deployment와 Service 리소스를 정의하여 배포한다.
2.1 레지스트리 배포 명세 (registry.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
namespace: registry
spec:
replicas: 1
selector:
matchLabels:
run: registry
template:
metadata:
labels:
run: registry
spec:
containers:
- name: registry
image: registry:2
ports:
- containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: registry-service
namespace: registry
spec:
type: LoadBalancer
selector:
run: registry
ports:
- name: registry-tcp
port: 30100
targetPort: 5000
nodePort: 30100
위 명세를 통해 30100 포트로 접근 가능한 레지스트리 서비스를 생성한다. 이후 다음 명령어를 통해 k8s 내부 레지스트리로 이미지를 업로드할 수 있다.
docker push localhost:30100/ubuntu:22.04
3. 보안 및 데이터 영속성 구성
운영 환경 수준의 레지스트리를 구축하기 위해서는 SSL 인증서(HTTPS) 적용과 데이터 유실 방지를 위한 볼륨(Persistence) 설정이 필요하다.
3.1 SSL 인증서 발급 및 적용 (OpenSSL)
보안 통신을 위해 OpenSSL을 사용하여 자가 서명 인증서를 발급한다.
# 인증서 생성 (유효기간 3650일)
openssl req -newkey rsa:4096 -nodes -sha256 \
-keyout certs/registry.key \
-addext "subjectAltName = DNS:registry-service.registry.svc.cluster.local" \
-x509 -days 3650 -out certs/registry.crt
생성된 인증서는 Kubernetes의 Secret 리소스로 등록하여 파드(Pod)가 사용할 수 있도록 한다.
kubectl create secret tls registry-cert --cert=certs/registry.crt --key=certs/registry.key -n registry
3.2 볼륨 마운트 및 트러블슈팅
레지스트리 데이터의 영속성을 위해 PersistentVolume(PV)과 PersistentVolumeClaim(PVC)을 설정한다.
설정 내용: registry.yaml의 Deployment 명세에 volumeMounts를 추가하여 인증서 경로(/certs)와 데이터 경로(/var/lib/registry)를 연결한다.
- Windows 환경에서의 이슈:
- Windows Docker Desktop 환경에서
hostPath사용 시 경로 인식 문제가 발생할 수 있다. - 해결 방향: Docker Desktop 설정에서 'File Sharing'에 해당 경로를 추가하거나, 경로 표기법을
/run/desktop/mnt/host/c/Users/...또는 WSL2 경로 형식으로 변경하여 시도해야 한다.
- Windows Docker Desktop 환경에서
4. BDD 기반의 인수 테스트 방법론
인프라 구축이 완료되면, 실제 애플리케이션의 인수 테스트를 수행한다.
4.1 사용자 대면 테스트와 BDD
인수 테스트는 사용자 대면 테스트라고도 불리며, 기술적인 검증(Curl, Unit Test)을 넘어 사용자가 이해할 수 있는 언어로 작성되어야 한다. 이를 위해 BDD(Behavior Driven Development, 행위 주도 개발) 방법론을 적용한다.
- BDD의 핵심: 사용자가 테스트의 기준(시나리오)을 제시하고, 이를 바탕으로 개발자가 테스트 코드를 작성한다.
- 도구: Cucumber(자연어 기반 테스트 명세)와 Selenium(웹 브라우저 자동화)이 대표적이다.
4.2 인수 테스트 프로세스 (with Cucumber & Jenkins)
- 인수 기준 생성: "사용자가 로그인 버튼을 누르면 메인 페이지로 이동한다"와 같은 시나리오 작성.
- 스텝 정의(Step Definition): 시나리오를 실행할 코드(Java, Python 등) 작성.
- Jenkins 파이프라인 통합:
- Jenkins에서 도커 이미지를 빌드하고 사설 레지스트리로 푸시한다.
- 테스트 스테이지에서 해당 이미지를 기반으로 컨테이너를 실행한다.
- Cucumber를 통해 자동화된 인수 테스트를 수행하고 결과를 리포팅한다.
4.3 TDD와의 연계
인수 테스트 자동화는 TDD(Test Driven Development) 사이클의 가장 바깥 고리이다.
- 실패하는 인수 테스트 작성: 요구사항을 반영한 시나리오를 먼저 작성한다.
- 기능 구현: 테스트를 통과하기 위한 코드를 작성한다.
- 리팩토링: 코드를 개선한다.
결론적으로 인수 테스트는 단순한 버그 탐색이 아니라, "우리가 올바른 제품을 만들고 있는가?"를 검증하는, 기술보다는 사람(사용자) 중심의 활동이다.
'Programmers' 카테고리의 다른 글
| [71일차]오픈소스 기여 방법 (0) | 2025.12.22 |
|---|---|
| [70일차]IaC 기반의 인프라 자동화 및 CI/CD 파이프라인 고도화 (0) | 2025.12.19 |
| [68일차]CI/CD 환경 구축을 위한 Jenkins(젠킨스)의 이해와 활용 (1) | 2025.12.17 |
| [67일차]쿠버네티스(Kubernetes)를 활용한 웹 개발 배포 시스템 이해 (0) | 2025.12.16 |
| [66일차]웹 개발 파이프라인 구축과 도커(Docker)의 활용 (1) | 2025.12.15 |