요약
수동 요청 실행 중에 설정된 변수는 Postman의 컬렉션 러너에서 동일한 컬렉션을 실행하면 종종 사라집니다. 근본 원인은 변수 스코프 불일치입니다. `pm.environment.set`은 수동 모드에서와 러너에서 다르게 동작하며, 컬렉션 변수는 환경 변수와 다르게 작동합니다. 이 가이드는 이러한 현상이 발생하는 정확한 이유와 해결 방법을 설명하고, Apidog가 실수로 잘못 구성될 가능성이 낮은 방식으로 변수 스코프를 처리하는 방법을 보여줍니다.
소개
Postman에서 API를 수동으로 테스트해 왔습니다. 로그인 요청을 실행하면 사전 요청 스크립트가 인증 토큰을 설정하고, 후속 요청들이 이를 잘 가져옵니다. 모든 것이 정상적으로 작동합니다.
그러다 “컬렉션 실행(Run Collection)”을 클릭합니다. 러너가 시작되고, 로그인 요청은 성공하지만 다음 요청은 401 오류와 함께 실패합니다. 토큰이 없습니다.
이 시나리오는 Stack Overflow와 Postman 커뮤니티 포럼에서 반복적으로 나타납니다. 답변들은 보통 변수 스코프를 지적하지만, 수동 테스트와 러너 간에 동작이 왜 다른지에 대한 완전한 그림은 거의 설명하지 않습니다.
이를 이해하려면 Postman의 변수 스코프 계층 구조를 이해해야 합니다. 명확하게 이해하면 해결책은 간단합니다.
Postman의 변수 스코프 계층 구조
Postman에는 우선순위가 높은 것부터 낮은 순으로 나열된 5가지 변수 스코프가 있습니다.
- 로컬 변수(Local variables) – 현재 스크립트 실행 내에서만 사용 가능하며, 요청 간에 접근할 수 없음
- 데이터 변수(Data variables) – 데이터 기반 실행을 위해 CSV 또는 JSON 파일에서 로드됨
- 컬렉션 변수(Collection variables) – 컬렉션에 스코프가 지정되며, 해당 컬렉션 내의 요청 간에 유지됨
- 환경 변수(Environment variables) – 선택된 환경에 스코프가 지정되며, 컬렉션 간에 유지됨
- 글로벌 변수(Global variables) – 모든 환경의 모든 컬렉션에서 사용 가능함
Postman이 `{{token}}`과 같은 변수 참조를 해결할 때, 이 목록을 아래로 탐색하며 처음 일치하는 항목을 사용합니다.
문제는 "유지(persist)"가 컬렉션을 실행하는 방식에 따라 다르게 해석된다는 것입니다.
컬렉션 러너에서 변수가 사라지는 이유
현재 값과 초기 값의 차이
모든 Postman 변수에는 "초기 값(initial value)"과 "현재 값(current value)"이라는 두 가지 필드가 있습니다.
- 초기 값(Initial value)은 Postman 클라우드에 동기화되며 팀원들과 공유됩니다.
- 현재 값(Current value)은 사용자 컴퓨터에 로컬로 저장되며 절대 동기화되지 않습니다.
스크립트에서 `pm.environment.set('token', value)`를 사용하여 프로그래밍 방식으로 변수를 설정하면, Postman은 활성 환경의 **현재 값**을 업데이트합니다.
수동 테스트 모드에서는 로컬 현재 값이 동일한 세션 내에서 개별 요청 실행 간에 유지되므로 예상대로 작동합니다.
컬렉션 러너에서는 동작이 변경됩니다. 러너는 각 실행을 실행 시작 시점의 환경 현재 상태에서 시작합니다. 실행 중에 변수를 업데이트하는 스크립트는 해당 실행 내에서 올바르게 작동합니다. 그러나 러너가 실행 간에 변수를 지우도록 구성되었거나 초기 값이 비어 있고 러너가 새로운 환경 스냅샷을 사용하는 경우, 스크립트가 실행되더라도 변수가 유지되지 않는 것처럼 보일 수 있습니다.
환경 변수 대 컬렉션 변수 문제
여기에 더 흔한 함정이 있습니다. 응답 후 스크립트에서 변수를 설정하고 있습니다.
pm.environment.set('token', pm.response.json().access_token);
이것은 **활성 환경**에 변수를 설정합니다. 하지만 컬렉션 러너에는 “변수 값 유지(Keep variable values)”라는 옵션이 있습니다. 이 체크박스가 선택 해제되어 있으면(기본값은 선택 해제), 러너는 실행 후 환경 변수를 초기 값으로 재설정합니다. 실행 중에 설정된 모든 값은 버려집니다.
환경이 선택되지 않은 상태에서 컬렉션을 실행하는 경우, `pm.environment.set`은 소리 없이 실패합니다. 쓸 환경이 없습니다. 변수는 사라집니다.
수동 모드와 러너 모드 간의 스코프 불일치
수동 테스트에서는 일반적으로 환경이 선택되어 있으며 Postman 세션 전체에 걸쳐 유지됩니다. 요청을 실행하고, 변수를 설정하고, 다른 요청을 실행할 때, 이 모든 작업은 동일한 영구 환경 컨텍스트에서 발생합니다.
컬렉션 러너는 별도의 실행 컨텍스트를 생성합니다. 러너는 시작 시 환경 상태를 로드하고, 모든 요청을 실행한 다음 ( “변수 값 유지”를 선택하지 않는 한) 환경을 실행 전 상태로 되돌립니다.
이는 러너에서 한 요청에 의해 설정된 변수는 동일한 실행 내의 후속 요청에 사용할 수 있지만, 명시적으로 유지하도록 설정하지 않는 한 실행이 끝난 후 환경 패널에 유지되지 않는다는 것을 의미합니다.
해결 방법
해결 방법 1: 러너에서 “변수 값 유지” 확인하기
컬렉션 러너에서 실행을 클릭하기 전에:
- 러너 구성 패널에서 “변수 값 유지(Keep variable values)” 옵션을 찾습니다.
- 이 상자를 선택합니다.
이렇게 하면 러너가 실행 완료 후 변경된 변수 값을 활성 환경에 다시 쓰도록 지시합니다. 실행 중에 스크립트에 의해 설정된 변수는 실행이 완료될 때 환경 패널에 표시됩니다.
언제 사용해야 하는가: 다른 도구나 후속 실행에서 사용할 인증 토큰을 새로 고치는 등 러너가 공유 상태를 업데이트해야 할 때. (예: 인증 토큰 갱신)
언제 사용하지 말아야 하는가: 여러 번 반복하여 실행하고 반복 1에서 설정된 변수가 반복 2를 오염시킬 때. 이 경우, 데이터 파일을 사용하거나 각 반복 시작 시 변수를 명시적으로 재설정합니다.
해결 방법 2: 실행 중 상태 유지를 위해 환경 변수 대신 컬렉션 변수 사용하기
변수가 동일한 컬렉션 실행 내의 요청 간에만 공유되어야 하는 경우, 환경 변수 대신 컬렉션 변수를 사용하십시오.
// 로그인 요청의 응답 후 스크립트에서:
pm.collectionVariables.set('token', pm.response.json().access_token);
// 후속 요청의 사전 요청 스크립트에서:
const token = pm.collectionVariables.get('token');
컬렉션 변수는 환경이 선택되었는지 여부와 관계없이 러너에서 항상 사용할 수 있습니다. 이는 컬렉션 실행 기간 동안 유지됩니다. 컬렉션 내에서 설정되고 소비되는 값에 대해 올바른 스코프입니다.
해결 방법 3: 실행 전에 환경이 선택되어 있는지 확인하기
환경이 활성화되어 있지 않으면 `pm.environment.set`은 소리 없이 실패합니다. 컬렉션을 실행하기 전에:
- 컬렉션 러너를 엽니다.
- “환경(Environment)” 드롭다운에서 환경이 선택되어 있는지 확인합니다.
- 환경 수준 변수가 필요하지 않은 경우, 대신 컬렉션 변수를 사용합니다 (해결 방법 2).
해결 방법 4: 항상 존재해야 하는 변수에 초기 값 사용하기
`baseUrl`과 같은 변수가 실행의 첫 번째 요청부터 사용 가능해야 하는 경우, 환경에서 현재 값뿐만 아니라 초기 값으로 설정하십시오.
환경 편집기에서:
- “현재 값(Current value)” 필드뿐만 아니라 “초기 값(Initial value)” 필드도 설정합니다.
- 초기 값은 러너가 시작 상태로 사용하는 값입니다.
현재 값만 설정되어 있고 러너가 로컬 현재 값에 접근할 수 없는 경우(예: 팀원이 컬렉션을 실행하거나 Newman/Apidog CLI 실행), 변수는 비어 있는 상태로 시작됩니다.
해결 방법 5: 콘솔 로깅으로 디버깅하기
사전 요청 및 응답 후 스크립트에 `console.log`를 추가하여 정확히 어떤 일이 일어나는지 확인하십시오.
// 사전 요청 스크립트
console.log('요청 전 토큰:', pm.collectionVariables.get('token'));
console.log('환경 토큰:', pm.environment.get('token'));
컬렉션을 실행하기 전에 Postman 콘솔(보기 > Postman 콘솔 표시)을 엽니다. 로그는 각 변수가 어떤 스코프에서 읽히고 각 단계에서 어떤 값을 가지고 있는지 정확히 보여줄 것입니다.
Apidog가 변수 스코프를 처리하는 방법
Apidog는 전역, 환경, 컬렉션, 로컬이라는 동일한 스코프 계층 구조를 사용합니다. 주요 차이점은 UI에 있습니다.
Apidog의 변수 편집기에서는 초기 값과 현재 값이 명시적인 레이블과 색상으로 표시됩니다. 인터페이스는 실수로 현재 값만 설정하는 것을 더 어렵게 만듭니다. 스크립트가 `pm.environment.set`을 사용하여 변수를 설정하면(Apidog는 Postman 호환성을 위해 이를 지원함), 환경 패널이 실시간으로 시각적으로 업데이트되어 변경 사항을 즉시 확인할 수 있습니다.
Apidog의 테스트 러너는 명시적으로 구성하지 않는 한 단계 사이에 변수 값을 재설정하지 않습니다. 기본 동작은 실행 중 요청 간에 변수 상태를 유지하는 것으로, 이는 대부분의 개발자가 수동 테스트에서 기대하는 것과 일치합니다.
팀 시나리오의 경우, Apidog의 로컬 우선 모델은 환경 변수가 디스크에 저장됨을 의미합니다. 실행 간에 현재 값을 덮어쓰는 클라우드 동기화는 없습니다.
일반적인 실수 요약
| 실수 | 증상 | 해결 방법 |
|---|---|---|
| 환경이 선택되지 않음 | pm.environment.set이 소리 없이 실패함 |
환경을 선택하거나 컬렉션 변수 사용 |
| 현재 값만 설정됨 | CI 또는 팀원의 컴퓨터에서 변수 누락 | 환경 편집기에서 초기 값 설정 |
| 변수 값 유지(Keep variable values)가 선택 해제됨 | 러너 완료 후 변수 재설정 | 러너 구성에서 "변수 값 유지" 확인 |
| 실행 중 상태에 환경 변수 사용 | 수동 모드에서는 작동하지만 러너에서는 실패함 | pm.collectionVariables.set으로 전환 |
| 로그에서 잘못된 스코프 확인 | 변수는 존재하지만 잘못된 값이 사용됨 | 두 스코프 모두 로깅하고 해결 우선순위 확인 |
자주 묻는 질문
`pm.environment.set`은 수동 모드에서는 작동하지만 러너에서는 왜 작동하지 않나요?수동 모드에서는 영구적인 환경 세션이 있습니다. 러너에서는 실행 시작 시 환경이 로드되고 기본적으로 실행 종료 시 재설정됩니다. 실행 중에 변수를 설정하는 스크립트는 해당 실행의 후속 요청에 여전히 작동하지만, “변수 값 유지”가 선택되지 않는 한 변경 사항은 환경에 유지되지 않습니다.
`pm.environment.set`과 `pm.collectionVariables.set`의 차이점은 무엇인가요?`pm.environment.set`은 활성 환경에 쓰며, 이 환경은 해당 환경을 사용하는 모든 컬렉션에서 공유됩니다. `pm.collectionVariables.set`은 특정 컬렉션에 연결된 스코프에 씁니다. 단일 컬렉션 실행 내에서만 중요한 값의 경우, 컬렉션 변수가 더 적절하며 환경을 선택할 필요가 없습니다.
이 문제는 Newman에서도 발생하나요?네. Newman도 동일한 스코프 모델을 가지고 있습니다. 기본적으로 Newman은 각 실행을 내보낸 환경의 초기 값으로 시작하며, `—export-environment` 플래그를 사용하여 최종 환경 상태를 파일에 쓰지 않는 한 실행 후 변경 사항을 유지하지 않습니다.
Newman의 `--export-environment` 플래그는 무엇인가요?이것은 Newman에게 실행 완료 후 실행 중에 스크립트에 의해 설정된 모든 값을 포함하여 환경의 최종 상태를 JSON 파일에 쓰도록 지시합니다. 그런 다음 해당 파일을 다음 실행을 위한 환경으로 전달할 수 있습니다. 이는 한 실행이 다음 실행에서 사용될 토큰을 생성하는 파이프라인에 유용합니다.
Apidog는 `pm.collectionVariables.set`을 지원하나요?네. Apidog는 `pm.collectionVariables.set`, `pm.collectionVariables.get`, `pm.environment.set`, `pm.environment.get`을 포함한 전체 Postman 스크립팅 API를 지원합니다. Postman에서 마이그레이션된 컬렉션은 동일한 스크립트 구문을 사용합니다.
Postman에서 한 컬렉션에서 다른 컬렉션으로 변수를 전달하려면 어떻게 해야 하나요?글로벌 변수를 사용합니다: `pm.globals.set('token', value)`. 글로벌 변수는 Postman 세션 수명 동안 컬렉션과 환경 전체에 걸쳐 유지됩니다. 글로벌 변수는 스코프가 지정되지 않아 이름 충돌을 일으킬 수 있으므로 팀 설정에서는 이 접근 방식에 주의해야 합니다.
Postman의 변수 스코프 문제는 API 테스트 스위트에서 잘못된 음성(false negative)을 유발하는 가장 확실한 원인 중 하나입니다. 수동으로 통과하지만 러너에서 실패하는 테스트는 신뢰할 수 없는 테스트입니다. 스코프 모델을 이해하고, 올바른 컨텍스트에 올바른 세터를 사용하고, 필요할 때 “변수 값 유지”를 확인하는 것이 이러한 문제의 대부분을 해결하는 세 가지 핵심 조치입니다.
