DEV Community

Cover image for วิธีเพิ่มการแยกเงื่อนไข If/Else และการควบคุมโฟลว์สำหรับสถานการณ์ทดสอบ API ใน Apidog
Thanawat Wongchai
Thanawat Wongchai

Posted on • Originally published at apidog.com

วิธีเพิ่มการแยกเงื่อนไข If/Else และการควบคุมโฟลว์สำหรับสถานการณ์ทดสอบ API ใน Apidog

การทดสอบ API แบบเส้นตรงมักเรียก logincheckoutreceipt แล้วตรวจสอบผลลัพธ์ตามลำดับ แต่เมื่อขั้นตอนที่ต้องพึ่งพากันล้มเหลว ผลลัพธ์จะทำให้วิเคราะห์สาเหตุได้ยาก เช่น หาก login ส่งคืน 401 การเรียก checkout ต่อไปไม่มีประโยชน์ และอาจสร้างข้อผิดพลาดรองที่กลบปัญหาจริงได้ วิธีที่ดีกว่าคืออ่านผลลัพธ์จากการเข้าสู่ระบบ ตัดสินใจว่าจะดำเนินการต่อหรือไม่ และรายงานจุดที่ล้มเหลวให้ชัดเจน

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

ตรรกะแบบนี้เรียกว่า conditional logic และสร้างได้ด้วย flow control บทความนี้จะแสดงวิธีใช้ Conditional Branching ใน Apidog เพื่อสร้าง flow แบบ if/else: เข้าสู่ระบบ ตรวจสอบ status code และทำ checkout เฉพาะเมื่อเข้าสู่ระบบสำเร็จเท่านั้น

หากยังไม่เคยสร้าง Test Scenario มาก่อน ให้เริ่มจากบทความ วิธีเขียนสถานการณ์การทดสอบด้วย Apidog สำหรับพื้นฐานการทดสอบแบบเส้นตรง และอ่าน คู่มือ MDN เกี่ยวกับคำสั่งเงื่อนไข สำหรับแนวคิด if/else

การควบคุมโฟลว์คืออะไร และอะไรที่ไม่ใช่การควบคุมโฟลว์

ใน Apidog การทดสอบอัตโนมัติอยู่ในโมดูล Tests และหน่วยหลักคือ Test Scenario ซึ่งคล้าย Collection ใน Postman

ภายใน Scenario คุณสามารถเรียง Test Steps ได้หลายประเภท:

  • คำขอ API
  • Conditional Branching
  • Loop
  • Wait
  • องค์ประกอบ control flow อื่น ๆ

ตัวอย่าง Test Scenario ใน Apidog

Flow control ช่วยให้ Scenario ไม่ได้ทำงานเพียงตามลำดับ แต่สามารถตัดสินใจ ทำซ้ำ หรือหน่วงเวลาได้ เอกสาร Flow Control และ Conditional Branching ของ Apidog อธิบายตัวเลือกและป้ายกำกับใน UI โดยละเอียด

Conditional Branching คือชื่อฟีเจอร์ if/else ของ Apidog

อย่าสับสนระหว่าง branching กับ loop:

เครื่องมือ ใช้เมื่อ
Conditional Branching ต้องตัดสินใจครั้งเดียวว่าจะรันบล็อกหรือไม่
For Loop / ForEach Loop ต้องรันบล็อกซ้ำตามจำนวนครั้งหรือรายการข้อมูล

ตัวอย่าง: หากต้องตรวจสอบรายการ order ID หลายรายการ ให้ใช้ ForEach Loop ไม่ใช่ branching ดูรายละเอียดใน บทช่วยสอน ForEach Loop

เอกสาร Apidog ไม่ได้ระบุข้อจำกัดแยกตามแผนสำหรับ flow control, conditional branching, loop หรือการส่งข้อมูลระหว่างขั้นตอน และไม่ได้ระบุความต่างของฟีเจอร์เหล่านี้ระหว่าง Cloud กับ self-hosted

สร้าง Scenario ที่แยกสาขาตามผลลัพธ์จาก Login

เป้าหมายของเราคือ:

Login
  ├─ status = 200  → Checkout
  └─ status ≠ 200  → รายงานความล้มเหลวและหยุด
Enter fullscreen mode Exit fullscreen mode

ขั้นตอนที่ 1: สร้าง Test Scenario

  1. เปิด Apidog และไปที่โมดูล Tests
  2. คลิก + ข้างแถบค้นหา
  3. สร้าง Test Scenario
  4. เลือกไดเรกทอรีและกำหนดความสำคัญ
  5. กดสร้าง

ตอนนี้คุณจะมี Scenario เปล่าพร้อมเพิ่ม Test Steps

ขั้นตอนที่ 2: เพิ่มคำขอ Login เป็นขั้นตอนแรก

เพิ่ม Test Step แบบ custom request แล้วกำหนดเป็น POST ไปยัง endpoint สำหรับยืนยันตัวตน:

POST https://api.your-store.com/v1/login
Content-Type: application/json

{
  "email": "dana@example.com",
  "password": "correct-horse-battery-staple"
}
Enter fullscreen mode Exit fullscreen mode

รันคำขอนี้ก่อนหนึ่งครั้งเพื่อยืนยันว่าผลลัพธ์ถูกต้อง ตัวอย่าง response เมื่อ login สำเร็จ:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "userId": "usr_10482"
}
Enter fullscreen mode Exit fullscreen mode

ในตัวอย่างนี้ เราจะใช้ status code 200 เป็นเงื่อนไขสำหรับไปยังขั้นตอน checkout

ขั้นตอนที่ 3: เข้าโหมด Orchestrate

คลิก Test Step ใดก็ได้เพื่อเข้าโหมด Orchestrate

  • แผงซ้าย: แสดง flow ของ Scenario
  • แผงขวา: แสดงการตั้งค่าของ Step ที่เลือก
  • ลากไอคอน เพื่อเรียงลำดับ Step ใหม่

โหมดนี้คือพื้นที่หลักสำหรับเพิ่มและจัดการ branching

ขั้นตอนที่ 4: เพิ่ม Conditional Branching

  1. คลิก Add Step
  2. เลือก Conditional Branching
  3. Apidog จะสร้างบล็อก If เปล่าให้หนึ่งบล็อก
  4. กำหนดเงื่อนไขเป็น:
Login response status Equals 200
Enter fullscreen mode Exit fullscreen mode

Apidog รองรับ judgment operators หลายแบบ เช่น:

  • Equals
  • Does not equal
  • Exists
  • Does not exist
  • Less than
  • Less than or equal
  • Greater than
  • Greater than or equal
  • Matches with Regex
  • Contains
  • Does not contain
  • Is empty
  • Is not Empty
  • In List
  • Not in List

สำหรับกรณี login นี้ ใช้ Equals กับค่า 200 ก็เพียงพอ

ขั้นตอนที่ 5: อ้างอิงผลลัพธ์ของ Step ก่อนหน้า

คุณสามารถนำผลลัพธ์จาก login มาใช้ในเงื่อนไขได้ 2 วิธี

วิธีที่ 1: ใช้ Retrieve pre-step data

คลิกช่องค่าของเงื่อนไข แล้วคลิกไอคอนไม้กายสิทธิ์ จากนั้นเลือก Retrieve pre-step data

Apidog จะให้เลือกข้อมูลจาก Step ก่อนหน้า เช่น status code หรือข้อมูลใน response body

รูปแบบอ้างอิงเบื้องหลังคือ:

{{$.<step id>.response.body.<field path>}}
Enter fullscreen mode Exit fullscreen mode

ตัวอย่าง หาก login คือ Step ID 1 และต้องการ token:

{{$.1.response.body.token}}
Enter fullscreen mode Exit fullscreen mode

ตัวอย่าง Retrieve pre-step data

ข้อควรทราบ:

  • Retrieve pre-step data ใช้ได้เฉพาะในโมดูล Tests
  • ต้องรันทั้ง Scenario จึงจะ resolve ค่าได้
  • หากรันเฉพาะ Step เดียว ค่าอ้างอิงอาจว่าง ซึ่งเป็นพฤติกรรมปกติ

วิธีที่ 2: Extract Variable จาก response

หากต้องใช้ token ซ้ำในหลาย Step หรือหลายโมดูล ให้สร้างตัวแปรแบบมีชื่อแทน

ใน Step login:

  1. เปิด Post-processors
  2. เพิ่ม Extract Variable
  3. ใช้ JSONPath เพื่อดึง token
$.token
Enter fullscreen mode Exit fullscreen mode

ตั้งชื่อตัวแปรเป็น token แล้วอ้างอิงใน Step ถัดไปได้ด้วย:

{{token}}
Enter fullscreen mode Exit fullscreen mode

วิธีนี้เหมาะกับข้อมูลที่ต้องใช้ซ้ำ เช่น access token, user ID หรือ order ID อ่านเพิ่มเติมได้ที่ วิธีส่งข้อมูลระหว่างขั้นตอนการทดสอบ

สำหรับการตรวจสอบ status code อย่างเดียว การใช้ Retrieve pre-step data คือวิธีที่สั้นที่สุด

ขั้นตอนที่ 6: เพิ่ม Else branch

เลื่อนเมาส์ไปที่บล็อก If แล้วคลิก + Else

จากนั้นกำหนดแต่ละสาขา:

  • If: เพิ่มคำขอ checkout ซึ่งจะทำงานเมื่อ login ส่งคืน 200
  • Else: เพิ่ม Step สำหรับบันทึกหรือแจ้งเตือนความล้มเหลว

ตัวอย่าง request สำหรับ checkout:

POST https://api.your-store.com/v1/checkout
Authorization: Bearer {{token}}
Content-Type: application/json

{
  "cartId": "cart_123"
}
Enter fullscreen mode Exit fullscreen mode

การใช้ Bearer token ใน header Authorization เป็นรูปแบบเดียวกับคำขอที่ต้องยืนยันตัวตนใน Stripe API documentation

สำหรับ Else branch คุณสามารถเลือกได้ เช่น:

  • ส่ง request ไปยัง logging endpoint
  • ส่ง notification ไปยังระบบแจ้งเตือน
  • เพิ่ม custom request พร้อม assertion ที่ล้มเหลวเสมอ เพื่อให้รายงานระบุความผิดพลาดชัดเจน

ผลลัพธ์จะมีตรรกะดังนี้:

if login.status === 200:
  run checkout
else:
  report failure
  stop
Enter fullscreen mode Exit fullscreen mode

ขั้นตอนที่ 7: บันทึกและทดสอบ

คลิก Save All เพื่อบันทึก Scenario

จากนั้นรันทั้ง Scenario สองกรณี:

  1. ใช้ข้อมูลรับรองที่ถูกต้อง — ควรเข้าสู่ If branch และรัน checkout
  2. ใช้ข้อมูลรับรองที่ไม่ถูกต้อง — ควรเข้าสู่ Else branch

การทดสอบทั้งสองเส้นทางช่วยยืนยันว่า Scenario ไม่ดำเนินการ checkout ต่อเมื่อ login ล้มเหลว

รูปแบบการใช้งาน Conditional Branching เพิ่มเติม

เมื่อ if/else พื้นฐานทำงานแล้ว คุณสามารถขยายรูปแบบนี้ได้หลายแบบ

แยกสาขาตามฟิลด์ใน response body

ไม่จำเป็นต้องตรวจเฉพาะ status code

สมมติ API login ส่งคืน 200 แม้บัญชีถูกล็อก แต่มี field status:

{
  "status": "locked"
}
Enter fullscreen mode Exit fullscreen mode

คุณสามารถอ้างอิงค่าได้ด้วย:

{{$.1.response.body.status}}
Enter fullscreen mode Exit fullscreen mode

แล้วกำหนดเงื่อนไขเป็น:

Equals "active"
Enter fullscreen mode Exit fullscreen mode

หรือใช้ operator อื่นตามกรณี:

Contains "active"
In List ["admin", "editor"]
Greater than 0
Enter fullscreen mode Exit fullscreen mode

ใช้ branching ร่วมกับ ForEach Loop

คุณสามารถใส่ Conditional Branching ไว้ภายใน ForEach Loop ได้

ตัวอย่าง flow:

ForEach productId:
  if product.stock > 0:
    add product to order
  else:
    skip product
Enter fullscreen mode Exit fullscreen mode

การอ้างอิง index ของ loop:

{{$.<loop step id>.index}}
Enter fullscreen mode Exit fullscreen mode

การอ้างอิง element ปัจจุบัน:

{{$.<loop step id>.element.<field path>}}
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างการใช้ Branching กับ Loop

อ่านรายละเอียดเพิ่มได้ใน บทช่วยสอน ForEach Loop

หยุด Loop ก่อนกำหนดด้วย Break If

ใน loop คุณสามารถใช้ Break If condition เพื่อยุติ loop ทันทีเมื่อเงื่อนไขเป็นจริง

ตัวอย่าง:

หยุด loop เมื่อพบ order ที่มีสถานะ "failed"
Enter fullscreen mode Exit fullscreen mode

สามารถเพิ่ม Break If condition ได้มากกว่าหนึ่งจุดภายใน loop

จัดการข้อผิดพลาดใน Loop ด้วย On Error

องค์ประกอบ On Error อยู่ที่ต้น loop และไม่สามารถย้ายตำแหน่งได้ โดยรองรับพฤติกรรมหลัก:

ตัวเลือก พฤติกรรม
Ignore ไปยัง request ถัดไป
Continue ข้าม request ที่เหลือของรอบปัจจุบัน
Break execution หยุด loop แล้วทำงานต่อหลัง loop
End execution หยุด Scenario ทั้งหมด

เพิ่ม Wait ระหว่าง Step

หาก API ต้องใช้เวลาประมวลผลหลังคำขอเขียนข้อมูล ให้เพิ่ม Wait ระหว่าง Step

ตัวอย่าง:

Create order → Wait 1000 ms → Get order → Assert status
Enter fullscreen mode Exit fullscreen mode

ค่า Wait วัดเป็นมิลลิวินาที

ใช้ค่าจาก Step ก่อนหน้าใน Script

หากเงื่อนไขซับซ้อนเกินกว่า condition builder ให้คำนวณด้วย pre-processor หรือ post-processor script

ใน script อย่าใช้รูปแบบนี้โดยตรง:

{{token}}
Enter fullscreen mode Exit fullscreen mode

ให้ใช้:

const token = pm.variables.get("$.2.response.body.token");
Enter fullscreen mode Exit fullscreen mode

โดยต้องระบุ Step ID และ field path ให้ตรงกับ Scenario ของคุณ

สำหรับแนวทางเพิ่มเติม ดู คู่มือ request chaining และบทความ การจัดการการทดสอบ API และการส่งข้อมูล

Scenario ไม่สามารถอ้างอิงตัวเองได้ เพื่อป้องกันการวนซ้ำไม่รู้จบเมื่อซ้อน Scenario

รัน Conditional Branching ใน CI ด้วย Apidog CLI

Scenario ที่สร้างในแอปสามารถรันแบบ headless ใน CI ได้ด้วย Apidog CLI

ติดตั้ง CLI และล็อกอิน:

npm install -g apidog-cli
apidog login --with-token <YOUR_ACCESS_TOKEN>
Enter fullscreen mode Exit fullscreen mode

รัน Test Scenario ด้วย Scenario ID และ Environment ID:

apidog run --access-token $APIDOG_ACCESS_TOKEN -t <scenario_id> -e <env_id> -r cli
Enter fullscreen mode Exit fullscreen mode

พารามิเตอร์หลัก:

พารามิเตอร์ ความหมาย
-t Test Scenario ID
-e Environment ID
-r Reporter

Reporter ที่ใช้ได้ เช่น:

-r cli
-r html
-r junit
-r html,cli
Enter fullscreen mode Exit fullscreen mode

Conditional Branching จะทำงานเหมือนกับใน UI:

  1. CLI รัน login
  2. อ่าน response
  3. เลือก If หรือ Else branch
  4. ส่ง exit code ตามผลลัพธ์ของ Scenario

ดังนั้น หาก login ล้มเหลวและ Else branch ทำให้ Scenario fail ระบบ CI ก็สามารถทำให้ build ล้มเหลวได้ตามต้องการ

ดูวิธีติดตั้งและใช้งานเพิ่มเติม:

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

Conditional Branching และ Loop ต่างกันอย่างไร?

Conditional Branching ตัดสินใจครั้งเดียวว่าจะรันบล็อกหรือไม่ ส่วน Loop ใช้รันบล็อกซ้ำ

ใช้ branching สำหรับกรณี เช่น:

รัน checkout เฉพาะเมื่อ login สำเร็จ
Enter fullscreen mode Exit fullscreen mode

ใช้ For หรือ ForEach Loop สำหรับกรณี เช่น:

รัน request เดิมกับ order ID ทุกตัวใน array
Enter fullscreen mode Exit fullscreen mode

ดู บทช่วยสอน ForEach Loop สำหรับรายละเอียด loop

ทำไม Retrieve pre-step data จึงเป็นค่าว่าง?

สาเหตุหลักมีสองข้อ:

  1. ฟีเจอร์นี้ใช้ได้ในโมดูล Tests เท่านั้น ไม่ใช่ APIs
  2. ต้องรันทั้ง Scenario ไม่ใช่รัน Step เดียว

เมื่อรันเฉพาะ Step เดียว จะไม่มีผลลัพธ์จาก Step ก่อนหน้าให้ใช้อ้างอิง

แยกสาขาจาก field ใน response body ได้หรือไม่?

ได้ ตัวอย่าง:

{{$.1.response.body.status}}
Enter fullscreen mode Exit fullscreen mode

จากนั้นใช้ operator เช่น Equals, Contains หรือ In List

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

ใช้ตัวแปรใน Script อย่างไร?

ภายใน pre-processor หรือ post-processor script ให้ใช้:

pm.variables.get("$.2.response.body.token");
Enter fullscreen mode Exit fullscreen mode

แทนการใช้ {{variable}} โดยตรง

Conditional Branching มีค่าใช้จ่ายเพิ่มหรือใช้ได้เฉพาะ self-hosted หรือไม่?

เอกสาร Apidog ไม่ได้ระบุข้อจำกัดแยกตามแผนสำหรับ flow control, conditional branching, loops หรือการส่งข้อมูลระหว่าง Step และไม่ได้ระบุความต่างของฟีเจอร์เหล่านี้ระหว่าง Cloud กับ self-hosted

สรุป

การทดสอบแบบเส้นตรงบอกได้เพียงว่ามีบางอย่างผิดพลาด แต่การทดสอบแบบมี branching ช่วยระบุว่าความผิดพลาดเริ่มต้นที่ใด และป้องกันไม่ให้ Scenario รัน Step ที่ไม่ควรรันต่อ

แนวทางที่ใช้ได้ทันทีคือ:

  1. เพิ่ม Step สำหรับ login
  2. เพิ่ม Conditional Branching
  3. ใช้ Retrieve pre-step data หรือ extracted variable เพื่ออ่านผลลัพธ์จาก login
  4. กำหนด If branch สำหรับ status = 200
  5. เพิ่ม Else branch สำหรับบันทึกหรือรายงานความล้มเหลว
  6. รัน Scenario ผ่าน apidog run ใน CI

ลองใช้ Apidog ฟรี แล้วเปลี่ยนการทดสอบ API แบบเส้นตรงให้เป็น Scenario ที่ตัดสินใจตาม response จริงได้

Top comments (0)