DEV Community

Cover image for Postman Variable ไม่คงอยู่ใน Runner: สาเหตุและวิธีแก้ไข
Thanawat Wongchai
Thanawat Wongchai

Posted on • Originally published at apidog.com

Postman Variable ไม่คงอยู่ใน Runner: สาเหตุและวิธีแก้ไข

สรุปสาระสำคัญ (TL;DR)

ตัวแปรที่ตั้งค่าระหว่างการรันคำขอแบบแมนนวลใน Postman อาจ “หายไป” เมื่อรันผ่าน Collection Runner เพราะขอบเขตตัวแปรและพฤติกรรมการคงค่าระหว่างการรันไม่เหมือนกัน จุดที่ต้องตรวจสอบคือ pm.environment.set, การเลือก Environment, ค่า Initial/Current Value, ตัวเลือก “Keep variable values” และการเลือกใช้ Collection Variables ให้เหมาะกับสถานะภายในรันเดียวกัน

ลองใช้ Apidog วันนี้

บทนำ

คุณอาจเคยเจอสถานการณ์นี้:

  1. รันคำขอ Login ใน Postman แบบแมนนวล
  2. Post-response script ดึง access_token
  3. ตั้งค่า token ด้วย pm.environment.set
  4. คำขอถัดไปใช้ {{token}} ได้ตามปกติ
  5. แต่เมื่อกด Run Collection คำขอ Login ผ่าน แต่คำขอถัดไปได้ 401 Unauthorized

ตัวอย่างสคริปต์ที่มักเป็นต้นเหตุ:

pm.environment.set('token', pm.response.json().access_token);
Enter fullscreen mode Exit fullscreen mode

สคริปต์นี้ไม่ได้ผิดเสมอไป แต่จะมีปัญหาเมื่อ:

  • ไม่ได้เลือก Environment ใน Runner
  • Runner รีเซ็ตค่าหลังรันเสร็จ
  • ใช้ Environment Variables ทั้งที่ต้องการแค่ state ภายใน Collection Run
  • ตั้งค่าเฉพาะ Current Value แต่ไม่ได้ตั้ง Initial Value

บทความนี้สรุปวิธีดีบักและแก้ไขแบบลงมือทำได้ทันที

ลำดับชั้นขอบเขตตัวแปรของ Postman

Postman แก้ค่า {{variable}} ตามลำดับความสำคัญดังนี้:

  1. Local variables — ใช้เฉพาะในสคริปต์ที่กำลังรัน
  2. Data variables — มาจากไฟล์ CSV/JSON สำหรับ data-driven test
  3. Collection variables — ใช้ภายในคอลเล็กชัน
  4. Environment variables — ใช้ใน Environment ที่เลือก
  5. Global variables — ใช้ได้ข้ามคอลเล็กชันและ Environment

ถ้ามีตัวแปรชื่อเดียวกันหลายขอบเขต เช่น token Postman จะใช้ค่าจากขอบเขตที่มี priority สูงกว่าก่อน

ตัวอย่าง:

pm.collectionVariables.set('token', 'collection-token');
pm.environment.set('token', 'environment-token');

console.log(pm.variables.get('token'));
Enter fullscreen mode Exit fullscreen mode

pm.variables.get('token') จะคืนค่าตามลำดับ priority ไม่ได้หมายความว่าจะอ่านจาก Environment เสมอไป

ทำไมตัวแปรจึงหายไปใน Collection Runner

1. Current Value และ Initial Value ไม่เหมือนกัน

ตัวแปรใน Postman มี 2 ค่า:

  • Initial value: ค่าที่ซิงค์และแชร์กับทีม
  • Current value: ค่า local ในเครื่องของคุณ

เมื่อใช้:

pm.environment.set('token', value);
Enter fullscreen mode Exit fullscreen mode

Postman จะอัปเดต Current value ของ Environment ที่ใช้งานอยู่

ในโหมดแมนนวล ค่านี้มักอยู่ต่อใน session เดิม แต่ใน Collection Runner ค่าที่ถูกแก้ระหว่างรันอาจไม่ถูกเขียนกลับหลังจบรัน ถ้าไม่ได้เปิดตัวเลือกที่เกี่ยวข้อง

2. ไม่ได้เลือก Environment

ถ้า Runner ไม่มี Environment ที่ active อยู่ โค้ดนี้จะไม่มีที่ให้เขียนค่า:

pm.environment.set('token', pm.response.json().access_token);
Enter fullscreen mode Exit fullscreen mode

ผลคือคำขอถัดไปที่ใช้:

Authorization: Bearer {{token}}
Enter fullscreen mode Exit fullscreen mode

อาจได้ค่าว่าง แล้ว API ตอบ 401

3. Runner รีเซ็ตค่าหลังรันเสร็จ

Collection Runner มีตัวเลือก Keep variable values

ถ้าไม่ได้เลือก ตัวแปรที่ถูก set ระหว่างรันอาจถูกรีเซ็ตกลับหลังรันจบ

สิ่งที่ควรจำ:

  • ตัวแปรที่ตั้งระหว่างรันยังใช้ได้ภายในรันเดียวกัน
  • แต่หลังจบรัน ค่าอาจไม่คงอยู่ใน Environment panel
  • ถ้าต้องการให้ค่าคงอยู่ ต้องเลือก Keep variable values

4. ใช้ Environment Variables ผิดบริบท

ถ้าค่า token ใช้แค่ระหว่าง request ภายใน Collection Run เดียวกัน ไม่จำเป็นต้องเขียนลง Environment

ให้ใช้ Collection Variables แทน:

pm.collectionVariables.set('token', pm.response.json().access_token);
Enter fullscreen mode Exit fullscreen mode

แล้วคำขอถัดไปอ่านด้วย:

const token = pm.collectionVariables.get('token');
Enter fullscreen mode Exit fullscreen mode

หรือใช้ใน header:

Authorization: Bearer {{token}}
Enter fullscreen mode Exit fullscreen mode

วิธีแก้ไขแบบลงมือทำ

วิธีแก้ไข 1: เปิด “Keep variable values” ใน Collection Runner

ก่อนกด Run:

  1. เปิด Collection Runner
  2. เลือก Environment ให้ถูกต้อง
  3. เปิดตัวเลือก Keep variable values
  4. รันคอลเล็กชัน
  5. ตรวจสอบ Environment panel หลังรันเสร็จ

ใช้วิธีนี้เมื่อคุณต้องการให้ค่าที่เกิดขึ้นระหว่างรัน เช่น token ล่าสุด ถูกบันทึกกลับไปใช้ต่อในรันถัดไป

ไม่ควรใช้เมื่อคุณรันหลาย iterations แล้ว state จาก iteration ก่อนหน้าอาจไปรบกวน iteration ถัดไป

วิธีแก้ไข 2: ใช้ Collection Variables สำหรับ state ภายในรัน

ถ้า token ใช้เฉพาะภายในคอลเล็กชัน ให้เปลี่ยนจาก Environment Variables เป็น Collection Variables

ใน request Login ให้ใส่ใน Tests หรือ Post-response script:

const json = pm.response.json();

pm.test('login should return access_token', function () {
  pm.expect(json.access_token).to.exist;
});

pm.collectionVariables.set('token', json.access_token);
Enter fullscreen mode Exit fullscreen mode

ใน request ถัดไป ใช้ header:

Authorization: Bearer {{token}}
Enter fullscreen mode Exit fullscreen mode

หรืออ่านจาก script:

const token = pm.collectionVariables.get('token');

pm.test('token should exist before request', function () {
  pm.expect(token).to.exist;
});
Enter fullscreen mode Exit fullscreen mode

ข้อดี:

  • ไม่ต้องพึ่ง Environment ที่ active
  • เหมาะกับค่าที่ใช้เฉพาะในคอลเล็กชัน
  • ลดปัญหา Runner รีเซ็ต Environment

วิธีแก้ไข 3: ตรวจสอบว่าเลือก Environment แล้ว

ถ้าจำเป็นต้องใช้ pm.environment.set ให้ตรวจสอบก่อนว่า Runner เลือก Environment แล้ว

ตัวอย่าง defensive script:

const json = pm.response.json();
const token = json.access_token;

if (!token) {
  throw new Error('access_token not found in response');
}

pm.environment.set('token', token);

console.log('saved token to environment:', pm.environment.get('token'));
Enter fullscreen mode Exit fullscreen mode

ก่อนรัน:

  1. เปิด Runner
  2. เลือก Environment จาก dropdown
  3. ตรวจสอบว่ามีตัวแปรที่ต้องใช้ เช่น baseUrl, username, password
  4. ค่อยรันคอลเล็กชัน

ถ้าไม่ต้องการ Environment จริง ๆ ให้ใช้ pm.collectionVariables.set แทน

วิธีแก้ไข 4: ตั้ง Initial Value สำหรับตัวแปรที่ต้องมีตั้งแต่ต้น

ตัวแปรประเภท configuration เช่น baseUrl ควรมีค่าใน Initial Value

ตัวอย่าง:

baseUrl = https://api.example.com
Enter fullscreen mode Exit fullscreen mode

ถ้าคุณตั้งเฉพาะ Current Value เครื่องคุณอาจรันผ่าน แต่เพื่อนร่วมทีมหรือ CI อาจรันไม่ผ่าน เพราะไม่มีค่า local นี้

แนวทางที่แนะนำ:

  • baseUrl: ตั้ง Initial Value
  • clientId: ตั้ง Initial Value ถ้าไม่ใช่ secret
  • clientSecret: ระวังการแชร์ ควรใช้ Current Value หรือ secret management
  • token: มักใช้ Current Value หรือ Collection Variable เพราะเป็น runtime state

วิธีแก้ไข 5: ดีบักด้วย Postman Console

เพิ่ม log เพื่อตรวจสอบว่าค่าอยู่ใน scope ไหน:

console.log('pm.variables token:', pm.variables.get('token'));
console.log('collection token:', pm.collectionVariables.get('token'));
console.log('environment token:', pm.environment.get('token'));
console.log('global token:', pm.globals.get('token'));
Enter fullscreen mode Exit fullscreen mode

เปิด Console ได้ที่:

View > Show Postman Console
Enter fullscreen mode Exit fullscreen mode

จากนั้นรัน Collection แล้วดูว่า:

  • token ถูก set จริงหรือไม่
  • request ถัดไปอ่าน token จาก scope ไหน
  • มี token ชื่อเดียวกันในหลาย scope หรือไม่
  • ค่าเป็น undefined, null หรือ string ว่างหรือไม่

ตัวอย่าง flow ที่แนะนำ

Login request: บันทึก token

const json = pm.response.json();

pm.test('response contains access_token', function () {
  pm.expect(json.access_token).to.be.a('string').and.not.empty;
});

pm.collectionVariables.set('token', json.access_token);

console.log('token saved:', pm.collectionVariables.get('token'));
Enter fullscreen mode Exit fullscreen mode

Protected request: ตรวจสอบ token ก่อนส่ง

ใน Pre-request script:

const token = pm.collectionVariables.get('token');

if (!token) {
  throw new Error('Missing token. Make sure Login request runs before this request.');
}

console.log('using token:', token);
Enter fullscreen mode Exit fullscreen mode

ใน Headers:

Authorization: Bearer {{token}}
Enter fullscreen mode Exit fullscreen mode

ลำดับ request ใน Collection Runner

จัดลำดับให้ชัดเจน:

1. Login
2. Get profile
3. Create resource
4. Update resource
5. Delete resource
Enter fullscreen mode Exit fullscreen mode

ถ้า Protected request รันก่อน Login ตัวแปร token จะยังไม่มีค่า

วิธีที่ Apidog จัดการขอบเขตตัวแปร

Apidog ใช้แนวคิดขอบเขตตัวแปรคล้ายกัน เช่น global, environment, collection และ local แต่จุดที่ช่วยลดความผิดพลาดคือการแสดงผลใน UI

ในตัวแก้ไขตัวแปรของ Apidog ค่าเริ่มต้นและค่าปัจจุบันแสดงแยกกันอย่างชัดเจน ทำให้เห็นง่ายว่าคุณกำลังตั้งค่าที่ scope ไหน และค่าที่ใช้ตอนรันคืออะไร

Apidog ยังรองรับสคริปต์แบบ Postman เช่น:

pm.environment.set('token', value);
pm.environment.get('token');

pm.collectionVariables.set('token', value);
pm.collectionVariables.get('token');
Enter fullscreen mode Exit fullscreen mode

ดังนั้นถ้าย้ายคอลเล็กชันจาก Postman มาใช้งานต่อ สคริปต์ส่วนใหญ่ยังใช้ไวยากรณ์เดิมได้

สำหรับการรันทดสอบ Apidog ช่วยให้เห็นการเปลี่ยนแปลงของตัวแปรระหว่างขั้นตอนชัดเจนขึ้น ลดโอกาสที่คุณจะ set ค่าไว้ผิด scope โดยไม่รู้ตัว

สรุปข้อผิดพลาดที่พบบ่อย

ข้อผิดพลาด อาการ วิธีแก้ไข
ไม่ได้เลือก Environment pm.environment.set ไม่มีที่ให้เขียนค่า เลือก Environment หรือใช้ Collection Variables
ตั้งเฉพาะ Current Value รันผ่านในเครื่องตัวเอง แต่ล้มเหลวใน CI หรือเครื่องเพื่อนร่วมทีม ตั้ง Initial Value สำหรับค่าที่ต้องมีตั้งแต่เริ่ม
ไม่ได้เปิด “Keep variable values” ค่าถูกรีเซ็ตหลัง Runner จบ เปิด “Keep variable values” ถ้าต้องการเก็บค่าหลังรัน
ใช้ Environment Variable สำหรับ runtime state แมนนวลผ่าน แต่ Runner มีพฤติกรรมไม่ตรงกัน ใช้ pm.collectionVariables.set
มีตัวแปรชื่อเดียวกันหลาย scope อ่านค่าไม่ตรงกับที่คาด log ทุก scope และตรวจสอบ priority

คำถามที่พบบ่อย (FAQ)

ทำไม pm.environment.set ทำงานในโหมดแมนนวล แต่ไม่ทำงานใน Runner?

เพราะโหมดแมนนวลใช้ Environment session ที่คุณเลือกไว้โดยตรง ส่วน Runner โหลด Environment ตอนเริ่มรัน และอาจไม่เขียนค่าที่เปลี่ยนกลับหลังรันเสร็จ ถ้าไม่ได้เปิด “Keep variable values”

ควรใช้ pm.environment.set หรือ pm.collectionVariables.set?

ถ้าค่าใช้ข้ามหลายคอลเล็กชันหรือผูกกับ Environment เช่น baseUrl ให้ใช้ Environment Variables

ถ้าค่าใช้เฉพาะภายใน Collection Run เช่น token ที่ได้จาก Login ให้ใช้ Collection Variables

pm.collectionVariables.set('token', pm.response.json().access_token);
Enter fullscreen mode Exit fullscreen mode

ปัญหานี้เกิดกับ Newman ด้วยหรือไม่?

เกิดได้เช่นกัน Newman ใช้โมเดล scope คล้ายกัน โดยทั่วไปจะเริ่มจากไฟล์ Environment ที่ส่งเข้าไป และไม่บันทึกค่าที่เปลี่ยนระหว่างรันกลับไฟล์เดิมโดยอัตโนมัติ

ถ้าต้องการ export Environment หลังรัน ให้ใช้:

newman run collection.json \
  -e environment.json \
  --export-environment environment.updated.json
Enter fullscreen mode Exit fullscreen mode

--export-environment ใช้ทำอะไร?

ใช้บันทึกสถานะ Environment หลังรันเสร็จ รวมถึงค่าที่ถูกตั้งระหว่างรัน เช่น token ใหม่

จากนั้นสามารถใช้ไฟล์ที่ export เป็น input สำหรับรันถัดไปได้

Apidog รองรับ pm.collectionVariables.set หรือไม่?

รองรับ Apidog รองรับ Postman scripting API เช่น:

pm.collectionVariables.set('token', value);
pm.collectionVariables.get('token');
pm.environment.set('token', value);
pm.environment.get('token');
Enter fullscreen mode Exit fullscreen mode

จะส่งตัวแปรจากคอลเล็กชันหนึ่งไปอีกคอลเล็กชันได้อย่างไรใน Postman?

ใช้ Global Variables:

pm.globals.set('token', value);
Enter fullscreen mode Exit fullscreen mode

แต่ควรใช้ด้วยความระวัง เพราะ Global Variables ไม่มี scope เฉพาะ อาจเกิด name collision หรือทำให้ test อื่นอ่านค่าผิดได้

สรุป

ถ้า Collection Runner ทำให้ token หาย ให้ตรวจตามลำดับนี้:

  1. เลือก Environment แล้วหรือยัง
  2. ต้องใช้ Environment จริงไหม หรือควรใช้ Collection Variables
  3. เปิด “Keep variable values” หรือยัง ถ้าต้องการเก็บค่าหลังรัน
  4. ตัวแปรที่ต้องมีตั้งแต่ต้นมี Initial Value หรือไม่
  5. มีตัวแปรชื่อเดียวกันในหลาย scope หรือไม่
  6. ตรวจด้วย Postman Console ว่าค่าถูก set และอ่านจาก scope ไหน

สำหรับ runtime state ภายในคอลเล็กชัน เช่น auth token แนวทางที่ปลอดภัยคือใช้:

pm.collectionVariables.set('token', pm.response.json().access_token);
Enter fullscreen mode Exit fullscreen mode

แล้วให้ request ถัดไปใช้:

Authorization: Bearer {{token}}
Enter fullscreen mode Exit fullscreen mode

วิธีนี้ลดความคลาดเคลื่อนระหว่างการรันแบบแมนนวลและ Collection Runner ได้มากที่สุด

Top comments (0)