현대적인 애플리케이션 아키텍처에서 알림 시스템은 사용자 경험과 시스템 안정성을 유지하는 핵심 요소입니다. 시스템 장애, 작업 완료 알림 또는 보안 경고와 같은 중요 정보를 전달할 때 이메일은 가장 보편적인 수단입니다. 하지만 테스트 단계에서 실제 이메일 서버를 연동하면 테스트 속도가 느려지고, 불필요한 스팸 메일이 발송되는 부작용이 발생할 수 있습니다.
Bash Automated Testing System(Bats)은 이러한 문제를 해결하기 위해 셸 환경에서 경량화된 테스트 프레임워크를 제공합니다. Bats를 사용하면 실제 네트워크 호출 없이도 표준 출력(stdout)과 종료 상태 코드($status)를 분석하여 이메일 발송 로직의 정확성을 안전하게 검증할 수 있습니다.
테스트 환경 구성 및 구조
Bats 테스트 환경은 일반적으로 프로젝트 루트의 test/ 디렉토리에 위치하며, 다음과 같은 파일들로 구성됩니다.
- 테스트 스크립트: 실제 테스트 케이스가 정의된
*.bats파일 - 테스트 헬퍼: 공통 기능을 정의하는
test_helper.bash - 픽스처(Fixtures): 테스트에 필요한 데이터나 가짜 실행 파일들을 모아둔 디렉토리
Bats는 @test 데코레이터를 사용하여 개별 테스트를 정의하고, run 명령어로 대상 스크립트를 실행한 뒤 그 결과를 어설션(Assertion)으로 확인합니다.
이메일 발송 로직 시뮬레이션
기본 출력값 검증
이메일 본문이나 헤더가 올바르게 생성되는지 확인하는 가장 기본적인 방법은 표준 출력을 캡처하는 것입니다.
@test "이메일 헤더 및 본문 생성 확인" {
run generate_mail_content "admin@internal.net" "Server_Status" "Normal"
[ "$status" -eq 0 ]
[[ "${lines[0]}" == "Recipient: admin@internal.net" ]]
[[ "${lines[1]}" == "Subject: [Alert] Server_Status" ]]
}
@test "SMTP 연결 실패 시 에러 메시지 출력 확인" {
# 가상의 실패 상황 연출
run mock_send_command --trigger-failure
[ "$status" -ne 0 ]
[[ "$output" =~ "Connection timed out" ]]
}
테스트 스위트 구성 및 통합 관리
여러 개의 테스트 파일을 하나의 스위트로 묶어 실행함으로써 전체 시스템의 건전성을 한 번에 파악할 수 있습니다.
@test "알림 시스템 통합 검증 스위트" {
run bats "test/scenarios/mail_delivery.bats"
[ "$status" -eq 0 ]
# 총 5개의 테스트 케이스가 성공했는지 확인
[[ "${lines[-1]}" =~ "5 tests, 0 failures" ]]
}
주요 테스트 시나리오 설계
1. 정상 발송 성공 케이스
사용자 입력값이 유효할 때 스크립트가 0을 반환하고 대기열 추가 메시지를 출력하는지 확인합니다.
@test "유효한 수신자로 메일 전송 시 성공" {
run ./notifier.sh --to "dev@company.com" --msg "Build Success"
[ "$status" -eq 0 ]
[ "$output" = "Success: Message queued." ]
}
2. 비정상 입력 및 예외 처리
잘못된 이메일 형식이나 필수 인자 누락 시 시스템이 적절한 에러 코드를 반환하는지 검증합니다.
@test "잘못된 이메일 주소 형식 차단" {
run ./notifier.sh --to "invalid-addr" --msg "Data"
[ "$status" -eq 1 ]
[[ "$output" == *"Error: Invalid Address Format"* ]]
}
3. 대량 발송 로직 및 카운트 검증
루프를 통한 대량 발송 시 처리된 항목의 개수가 예상치와 일치하는지 확인합니다.
@test "벌크 발송 처리 개수 일치 여부" {
# 10명의 수신자에게 발송 시뮬레이션
run ./bulk_notifier.sh --list "test_recipients.txt"
[ "$status" -eq 0 ]
# 출력된 결과 행의 수가 10인지 확인
[ "${#lines[@]}" -eq 10 ]
}
효율적인 테스트를 위한 팁
Bats에서 제공하는 $output 변수는 전체 실행 결과를 문자열로 담고 있으며, $lines 배열은 결과값을 줄 단위로 접근할 수 있게 해줍니다. 특정 행의 데이터만 추출하여 비교할 때 유용합니다.
- 환경 변수 활용: 테스트 시에만 활성화되는 디버그 모드를 위해
export DEBUG_MODE=true와 같은 환경 변수를 주입하여 더 상세한 로그를 추적할 수 있습니다. - 병렬 실행: 테스트 케이스가 많아질 경우
bats -j [프로세스수]옵션을 사용하여 실행 시간을 단축할 수 있습니다. - 멱등성 유지: 테스트 종료 후 생성된 임시 파일이나 로그는
teardown()함수를 통해 깔끔하게 제거하여 매 실행마다 동일한 환경을 유지해야 합니다.
이러한 Bats 기반의 테스트 전략을 CI/CD 파이프라인에 통합하면, 코드 수정 시마다 알림 로직의 결함을 자동으로 발견할 수 있어 시스템의 신뢰성을 크게 향상시킬 수 있습니다.