← 홈Setup Tip

Setup Tip

Setup Tip — 내 셸 환경을 읽는 테스트는 내 셸을 테스트한다

로컬에서는 전부 통과하던 수집기 테스트가 CI에서 12개 중 11개 실패했다. 모듈이 공급자 API 키 환경 변수가 없으면 바로 예외를 던지게 되어 있었는데, 작업하던 셸에는 키가 있었고 CI에는 없었다. 키 확인은 프로그램 진입점으로 옮기고, 테스트는 필요한 환경 변수를 직접 세팅하거나 지운 상태에서 돌려야 한다. 그리고 로컬에서도 키를 뺀 채로 한 번 돌려 본다.

상황

외부 공급자 결과를 모으는 작은 수집기 모듈에 테스트 12개가 붙어 있었다. 작업 셸에서는 모두 통과했다. CI에서는 11개가 실패했다. 실패 메시지는 테스트 내용과 상관없이 모두 같았다. 공급자 API 키 환경 변수가 설정되지 않았다는 예외였다.

원인

모듈이 로드되거나 생성될 때 키가 있는지 확인하고, 없으면 바로 예외를 던졌다. 그 자체는 실제 실행에서는 친절한 동작이다. 문제는 테스트가 그 키를 쓰지 않는데도 같은 경로를 지나간다는 것이었다. 작업하던 셸에는 평소에 쓰던 키가 내보내져 있었고, CI 러너에는 당연히 없었다. 로컬의 초록불은 코드가 맞다는 증거가 아니라 내 셸에 키가 있다는 증거였다.

팁: 사전 확인은 진입점에서

"키가 없으면 실행하지 않는다" 같은 사전 확인은 사용자가 실제로 실행하는 CLI 스크립트나 서버 시작 지점에 둔다. 라이브러리 모듈 안에서 import 시점에 환경을 검사하면, 그 모듈을 불러오는 모든 테스트가 환경에 묶인다. 진입점에서 확인하면 실제 사용자는 여전히 명확한 오류를 받고, 테스트는 영향을 받지 않는다.

팁: 테스트가 환경을 직접 정한다

환경 변수에 의존하는 테스트는 그 값을 테스트 안에서 설정하고, 끝나면 원래대로 돌려놓는다. 반대로 "키가 없을 때 오류가 나는가"를 확인하는 테스트는 그 변수를 명시적으로 지운 상태에서 돈다. 어느 쪽이든 실행하는 사람의 셸에 무엇이 들어 있는지에 따라 결과가 바뀌면 안 된다.

팁: 로컬에서 깨끗한 환경으로 한 번

푸시하기 전에 env -u <변수명> <테스트 명령>처럼 의심 가는 변수를 빼고 한 번 돌린다. 더 확실하게는 env -i PATH="$PATH" HOME="$HOME" <테스트 명령>으로 거의 빈 환경에서 돌려 본다. CI에서 처음 발견할 실패를 몇 초 만에 로컬에서 볼 수 있다.

체크리스트

1) 실패 메시지가 테스트마다 같다면 환경부터 의심한다. 2) 모듈 로드 시점의 환경 검사를 찾는다. 3) 사전 확인을 진입점으로 옮긴다. 4) 테스트가 쓰는 환경 변수를 테스트 안에서 정한다. 5) 키를 뺀 환경에서 로컬로 한 번 돌린다.