본문으로 건너뛰기

Vapor 백엔드 배포 전 핵심 동작을 테스트하기

Writing Tests Before Shipping My First Vapor Backend in 2026 pt. 7

swiftsips.dev

핵심 요약

  1. LinkVault의 테스트 환경은 개발·운영 DB와 분리된 인메모리 SQLite를 사용하며, 테스트마다 마이그레이션을 실행하고 되돌려 데이터가 남지 않게 구성한다.
  2. VaporTesting과 Swift Testing으로 잘못된 가입 입력, 인증이 필요한 경로, 인증 사용자의 링크 생성, 사용자 간 링크 접근 차단을 검증한다.
  3. 테스트는 성공 경로뿐 아니라 입력 검증과 사용자 데이터 소유권 같은 경계를 확인해야 하며, 글은 이 패턴을 컬렉션·태그·큐 작업 등으로 확장할 기반을 마련한다.

도입

LinkVault에는 사용자 인증과 소유 링크, 입력 검증, 컬렉션·태그, 필터링·페이지네이션, 백그라운드 메타데이터 처리가 추가됐다. 기능이 늘어난 상태에서 인증이나 데이터 조회를 변경하면 보호 경로가 열리거나 다른 사용자의 링크가 노출될 수 있다. 배포 전 VaporTesting과 Swift Testing을 설정하고, 위험이 큰 동작 네 가지를 테스트한다.

상세 요약

테스트 환경 분리

LinkVault는 실제 앱에서 Postgres를 사용하고, 테스트에서는 인메모리 SQLite를 사용한다. Package.swift의 테스트 타깃에 VaporTesting과 XCTQueues를 추가하고, SQLite 드라이버를 앱 타깃에 연결한다. configure.swift에서는 환경이 .testing일 때 .sqlite(.memory)를 사용하고, 그 외에는 환경 변수로 설정한 Postgres 연결을 사용한다.

테스트용 앱을 만드는 withTestApp 도우미는 앱 생성, configure() 실행, 마이그레이션, 테스트 실행, 마이그레이션 되돌리기, 앱 종료 순서로 동작한다. 오류가 발생해도 마이그레이션 되돌리기와 종료를 시도한다. 테스트 스위트에는 @Suite("LinkVault API", .serialized)를 지정해 테스트를 직렬로 실행한다. 각 테스트는 새 데이터베이스 스키마에서 시작하므로 앞선 테스트의 데이터가 남아 결과에 영향을 줄 가능성을 줄인다.

네 가지 핵심 동작 검증

첫 테스트는 POST api/auth/signup에 잘못된 이메일, 빈 이름, 짧은 비밀번호를 보내고 .badRequest 응답을 확인한다. 이후 테스트에서 인증된 사용자가 필요하므로 signup 도우미도 둔다. 이 함수는 가입 요청을 보내고 응답을 AuthResponse로 디코딩해 인증 토큰을 반환한다.

  • 인증 없이 GET api/links를 호출하면 .unauthorized인지 확인한다.
  • 가입한 사용자의 bearer token으로 POST api/links를 요청한다. 응답이 .ok인지 확인하고, 반환된 링크의 제목과 URL, isRead == false를 검증한다. 이 테스트는 요청부터 인증, 검증, 컨트롤러, Fluent, 데이터베이스, 응답 DTO까지 이어지는 경로를 확인한다.
  • 사용자 A가 만든 링크를 사용자 B의 토큰으로 조회한다. 결과가 .notFound인지 확인해 다른 사용자의 링크에 접근할 수 없음을 검증한다. 컨트롤러의 조회 조건은 링크 ID뿐 아니라 소유자 ID도 필터링한다.

실행과 확장

Xcode에서는 Command+U로 테스트를 실행하고, 터미널에서는 swift test를 실행한다. 글은 모든 경우를 망라하기보다 잘못된 가입 데이터 거부, 보호 경로의 인증 요구, 인증된 링크 생성, 사용자 간 데이터 격리를 먼저 다룬다. 중복 이메일, 로그인 실패, 컬렉션, 태그, 필터링, 페이지네이션, 수정·삭제, 큐 디스패치와 메타데이터 작업도 같은 패턴으로 테스트할 수 있다.

핵심은 성공 경로만 확인하지 않는 것이다. 백엔드가 보호한다고 약속한 입력과 접근 경계를 테스트로 고정해야 한다. Swift Testing의 @Test, #expect, #require 사용법은 Swift Testing의 매크로와 주요 테스트 기능에서도 확인할 수 있다. 글은 시리즈 다음 편의 주제로 Docker, 환경 변수와 시크릿, 운영용 Postgres·Redis, 서버와 큐 워커 실행, 로깅, 헬스 체크, 보안 및 CORS, 배포를 예고한다. Vapor 5 베타와 10주년도 언급하지만, 이 편의 구현은 LinkVault 테스트 환경과 네 가지 동작 검증에 집중한다. Vapor 5 베타 관련 내용은 Swift 6.4와 Vapor 5 베타, 9월 Swift 생태계 주요 소식에서 다룬다.

결론

테스트의 초점은 모든 코드 줄을 검증하는 데 있지 않다. 입력 검증, 인증, 인증된 쓰기, 사용자 데이터 격리처럼 깨졌을 때 문제가 되는 약속을 확인하는 데 있다. 이 글은 인메모리 SQLite와 공통 앱 설정 도우미를 이용한 테스트 기반을 만들고, 같은 패턴을 로그인 실패와 컬렉션, 태그, 페이지네이션, 큐 작업 테스트로 확장할 수 있도록 한다.