DEV Community

Cover image for วิธีใช้การคิวรีฐานข้อมูลในการทดสอบ API ด้วย Apidog (MySQL, MongoDB, Redis)
Thanawat Wongchai
Thanawat Wongchai

Posted on • Originally published at apidog.com

วิธีใช้การคิวรีฐานข้อมูลในการทดสอบ API ด้วย Apidog (MySQL, MongoDB, Redis)

รหัสสถานะสีเขียวอาจหลอกคุณได้: endpoint POST /orders ส่งคืน 201 Created, response body ดูถูกต้อง และการทดสอบผ่าน แต่แถวในฐานข้อมูลถูกบันทึกด้วยสถานะที่ถูกต้องหรือไม่? สินค้าคงคลังถูกตัดจริงหรือไม่? การทดสอบที่ตรวจเฉพาะ HTTP response ยืนยันสิ่งที่ API บอก ไม่ใช่สิ่งที่ระบบ ทำ วิธีปิดช่องว่างนี้คืออ่านและตรวจสอบฐานข้อมูลโดยตรง

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

แนวทางคือกำหนดข้อมูลตั้งต้นที่รู้แน่ชัดก่อนส่งคำขอ เรียก API แล้ว query ตารางเพื่อยืนยันข้อมูลที่ถูกบันทึกจริง Apidog รองรับสิ่งนี้ผ่าน Database Connections และ Database Operation processor ซึ่งให้รัน SQL หรือคำสั่ง NoSQL เป็นส่วนหนึ่งของ test scenario เดียวกับ HTTP request ได้โดยไม่ต้องต่อสคริปต์ภายนอก หากเพิ่งเริ่มสร้าง scenario ให้ดูคู่มือ วิธีการเขียนสถานการณ์การทดสอบด้วย Apidog สำหรับพื้นฐานระดับ request และดูภาพรวม ฝั่งเซิร์ฟเวอร์ ของ MDN เพื่อทบทวนการจัดเก็บข้อมูลแบบสัมพันธ์

การดำเนินการฐานข้อมูลช่วยให้การทดสอบดีขึ้นอย่างไร

การทดสอบ API ที่ไม่ตรวจฐานข้อมูลเป็นการทดสอบแบบกล่องดำ: คุณเชื่อ response ของ API เป็นหลัก แต่บั๊กที่สำคัญมักอยู่ระหว่าง response กับข้อมูลที่ถูกบันทึกจริง เช่น

  • ฟิลด์ status ไม่ถูกอัปเดต
  • foreign key ชี้ไปยังข้อมูลที่ไม่มีอยู่
  • soft delete กลายเป็น hard delete
  • API ตอบสำเร็จ แต่ transaction ไม่ได้ commit

Database step ช่วยให้คุณทำสิ่งที่ HTTP test อย่างเดียวทำไม่ได้:

  1. กำหนดข้อมูลตั้งต้น ให้ทดสอบซ้ำได้และไม่พึ่งข้อมูลค้างในระบบ
  2. ตรวจสอบข้อมูลจริง ในแถวที่ API ระบุว่าเขียนแล้ว
  3. ดึงค่าจากฐานข้อมูล ไปใช้กับ request ถัดไป โดยไม่ต้องเดา ID หรือค่าที่เซิร์ฟเวอร์สร้าง

ใน Apidog ให้แยกการทำงานเป็น 2 ส่วน:

  1. สร้าง connection ที่ Settings > Database Connections
  2. เพิ่ม Database Operation เป็น
    • Pre Processor: ทำงานก่อน request
    • Post Processor: ทำงานหลัง request

Connection เดียวสามารถใช้ซ้ำได้กับทุก scenario ในโปรเจกต์

ฐานข้อมูลที่รองรับในแผนฟรี ได้แก่ MySQL, SQL Server 2014+, PostgreSQL และ Oracle ส่วน ClickHouse, MongoDB และ Redis ต้องใช้แผนแบบเสียเงิน


ขั้นตอนที่ 1: สร้าง Database Connection

เปิด Settings > Database Connections แล้วคลิก + New จากนั้นเลือกชนิดฐานข้อมูลและกรอกค่าเชื่อมต่อ:

  • Host เช่น db.staging.internal หรือ 127.0.0.1
  • Port เช่น 3306 สำหรับ MySQL
  • Username และ Password
  • Database name เช่น shop

หน้าจอการตั้งค่า Database Connection

หากฐานข้อมูลอยู่หลัง bastion host ให้ขยายส่วน SSH Tunnel แล้วกรอกรายละเอียด jump host

สำหรับ MySQL สามารถเลือก SSL mode ได้:

  • Prefer — ค่าเริ่มต้น: พยายามใช้ SSL แล้ว fallback หากใช้ไม่ได้
  • Require
  • Verify CA
  • Verify Full

เลือกโหมดที่เข้มงวดที่สุดตามที่เซิร์ฟเวอร์รองรับ แล้วคลิก Save

ข้อควรระวังสำหรับ MySQL 8

MySQL 8 อาจใช้ caching_sha2_password เป็น authentication plugin เริ่มต้น ซึ่งอาจทำให้เชื่อมต่อไม่ได้ หากพบ authentication error ให้เปลี่ยนผู้ใช้ทดสอบเป็น mysql_native_password:

ALTER USER 'tester'@'%'
IDENTIFIED WITH mysql_native_password BY '...';
Enter fullscreen mode Exit fullscreen mode

ดูรายละเอียดเพิ่มเติมในเอกสาร MySQL

ข้อมูลการเชื่อมต่อเก็บไว้ในเครื่อง

Database credentials เป็นข้อมูลแบบ local และไม่ sync ขึ้น cloud ดังนั้นสมาชิกทีมแต่ละคนต้องตั้งค่า connection เอง ดู workflow สำหรับทีมได้ที่ แชร์การตั้งค่าการเชื่อมต่อฐานข้อมูล


ขั้นตอนที่ 2: กำหนดข้อมูลตั้งต้นด้วย Pre Processor

สมมติว่ากำลังทดสอบการสร้างคำสั่งซื้อ คุณต้องการให้มี customer ที่สถานะใช้งานอยู่ก่อนเรียก POST /orders

เปิด request แล้วไปที่ Pre Processors:

  1. วางเมาส์ที่ Add Database Processor
  2. เลือก Database operation
  3. ตั้งชื่อ เช่น seed customer
  4. เลือก MySQL connection
  5. ใส่ SQL ใน Enter SQL Command
INSERT INTO customers (id, email, status)
VALUES ({{customer_id}}, '{{customer_email}}', 'active')
ON DUPLICATE KEY UPDATE status = 'active';
Enter fullscreen mode Exit fullscreen mode

ตัวแปร dynamic ใช้รูปแบบ {{variable_name}} จึงสามารถดึงค่าจาก environment ได้โดยตรง

ผลลัพธ์คือทุกครั้งที่ทดสอบ:

  • customer ที่ใช้ทดสอบมีอยู่จริง
  • customer มีสถานะ active
  • test case ไม่พึ่งลำดับการรันหรือข้อมูลตกค้างจากรอบก่อน

ขั้นตอนที่ 3: ตรวจสอบแถวในฐานข้อมูลด้วย Post Processor

เพิ่ม request สำหรับสร้างคำสั่งซื้อ:

POST /api/orders
Content-Type: application/json

{
  "customer_id": {{customer_id}},
  "items": [{ "sku": "APRON-01", "qty": 2 }]
}
Enter fullscreen mode Exit fullscreen mode

สมมติว่า response ส่งกลับ ID ของคำสั่งซื้อ และคุณเก็บไว้ในตัวแปร order_id

จากนั้นเพิ่ม Post Processor:

  1. เปิด Post Processors
    • โหมด DESIGN: อยู่ในแท็บ Run
    • โหมด DEBUG: อยู่ในแท็บ Request
  2. เลือก Add PostProcessor > Database operation
  3. ตั้งชื่อ เช่น verify order row
  4. เลือก database connection
  5. ใส่ SQL สำหรับอ่านข้อมูลคำสั่งซื้อ
SELECT id, status, total_cents
FROM orders
WHERE id = {{order_id}};
Enter fullscreen mode Exit fullscreen mode

ผลลัพธ์จาก query จะเป็น array ของ object เช่น:

[
  {
    "id": 101,
    "status": "pending",
    "total_cents": 2990
  }
]
Enter fullscreen mode Exit fullscreen mode

หากต้องการนำค่า status ไปใช้ต่อ:

  1. เปิด Extract Results (Optional)
  2. เพิ่ม Extract Result To Variable
  3. ตั้งค่า:
    • Variable Name: db_order_status
    • JSONPath Expression:
$[0].status
Enter fullscreen mode Exit fullscreen mode

ตอนนี้ db_order_status คือสถานะจากข้อมูลที่บันทึกในฐานข้อมูลจริง คุณจึงเพิ่ม assertion ให้ตรวจว่าเป็น pending ได้

ตัวอย่างบั๊กที่ขั้นตอนนี้ตรวจพบ:

  • API ส่ง 201 Created
  • response body ดูถูกต้อง
  • แต่แถวในตารางถูกบันทึกเป็น status = 'draft'

HTTP assertion อย่างเดียวอาจไม่เห็นบั๊กนี้ แต่ database assertion จะเจอทันที


ขั้นตอนที่ 4: ดึงค่าจากฐานข้อมูลไปใช้ใน request ถัดไป

การ extract ค่าไม่ได้มีไว้แค่ assertion บางครั้งฐานข้อมูลมีค่าที่ API ไม่ส่งกลับมา

ตัวอย่าง: การสร้างคำสั่งซื้อสร้าง fulfillment_ref ภายใน และบันทึกลงตาราง orders แต่ response ไม่มีฟิลด์นี้ อย่างไรก็ตาม request ถัดไปต้องเรียก:

GET /api/fulfillments/{ref}
Enter fullscreen mode Exit fullscreen mode

ให้ query ค่าใน Post Processor:

SELECT fulfillment_ref
FROM orders
WHERE id = {{order_id}};
Enter fullscreen mode Exit fullscreen mode

จากนั้นตั้งค่า extraction:

  • Variable Name: fulfillment_ref
  • JSONPath Expression:
$[0].fulfillment_ref
Enter fullscreen mode Exit fullscreen mode

request ถัดไปอ้างอิงค่าได้ทันที:

GET /api/fulfillments/{{fulfillment_ref}}
Enter fullscreen mode Exit fullscreen mode

รูปแบบนี้เหมือนการส่งค่าระหว่าง HTTP response แต่เปลี่ยนแหล่งข้อมูลจาก JSON response เป็นฐานข้อมูล ดูแนวทางเพิ่มเติมได้ที่ การส่งข้อมูลระหว่างขั้นตอนการทดสอบ และ การจัดระเบียบการทดสอบ API และการส่งข้อมูล


MongoDB และ Redis: ตัวเลือก NoSQL

Database Operation รองรับ NoSQL ด้วย แต่การตั้งค่าต่างจาก SQL และทั้ง MongoDB กับ Redis เป็นฟีเจอร์ในแผนแบบเสียเงิน ดูฟิลด์การตั้งค่าเพิ่มเติมได้จากเอกสาร Apidog

MongoDB

เพิ่ม Database Operation แล้วเลือก MongoDB จากนั้นเลือก Operation Type เช่น:

  • Find
  • Insert
  • Update
  • Delete
  • Run Database Command

สำหรับ CRUD ให้กำหนด Collection Name และใส่ JSON ใน Query Condition:

{ "_id": "65486728456e79993a150f1c" }
Enter fullscreen mode Exit fullscreen mode

Apidog จะแปลง ID string ที่ตรงกันเป็น ObjectId ให้อัตโนมัติ

หากต้องใช้ BSON type สามารถใช้ helper เช่น:

ISODate(...)
ObjectId(...)
NumberDecimal(...)
NumberLong(...)
Enter fullscreen mode Exit fullscreen mode

อ่านรายละเอียดประเภทข้อมูลได้จากเอกสาร MongoDB

เอกสาร MongoDB และ Redis ไม่ได้อธิบายกลไก Extract Result To Variable แบบเดียวกับ SQL อย่างชัดเจน ดังนั้นควรใช้ MongoDB สำหรับ seed data และตรวจสอบสถานะก่อน และตรวจสอบผลลัพธ์จริงใน Console ก่อนนำไปออกแบบ flow ที่ต้องพึ่งการ extract ค่า

Redis

Redis connection ต้องใช้:

  • Host
  • Port
  • Password
  • Database Index

การทำงานผ่าน UI รองรับ:

  • GET
  • SET
  • DELETE

ตัวอย่างการอ่าน session จาก cache:

Key: user:session:123
Operation Type: GET
Enter fullscreen mode Exit fullscreen mode

หากต้องใช้คำสั่งที่ UI ไม่มี ให้ใช้แท็บ Run Redis Command:

KEYS user:*
Enter fullscreen mode Exit fullscreen mode

ใช้ตรวจว่าระบบสร้าง cache key ตามที่คาดไว้ หรือล้าง key ก่อนทดสอบเพื่อยืนยันว่า endpoint เติม cache ใหม่ได้


ข้อจำกัดและกรณีใช้งานขั้นสูง

ก่อนขยาย test suite ให้พิจารณาข้อจำกัดเหล่านี้:

  • ForEach loop หากวนซ้ำข้อมูลใน ForEach ให้อ้างอิงข้อมูลของรอบปัจจุบันด้วย:
  {{$.StepID.element.field}}
Enter fullscreen mode Exit fullscreen mode

โดย StepID คือหมายเลขจริงของขั้นตอน ForEach

  • Conditional flow จากค่าใน DB

    extract ค่า เช่น status แล้วแยกเส้นทาง scenario ตามค่าได้ เช่น paid กับ pending ดูตัวอย่างที่ ตรรกะเงื่อนไขในสถานการณ์การทดสอบ API

  • Environment routing

    สร้าง connection แยกสำหรับแต่ละ environment แล้ว Apidog จะเลือก connection ตาม environment ที่เปิดใช้งาน

  • Stored procedures

    UI ไม่รองรับการทำงานซับซ้อน เช่น stored procedures ควรจำกัด SQL ใน test step ให้เป็นคำสั่งตรงไปตรงมา เช่น SELECT, INSERT, UPDATE และ DELETE

  • Oracle

    ต้องติดตั้ง Oracle Client บนเครื่องก่อนจึงเชื่อมต่อได้


แยกข้อมูลประจำตัวตาม environment

อย่าให้ test ไปกระทบ production โดยไม่ตั้งใจ สร้าง database connection แยกสำหรับแต่ละ environment เช่น:

  • local
  • staging

แต่ละ connection มี host, user และ password ของตัวเอง

เมื่อเปลี่ยน environment จากเมนูด้านขวาบน Apidog จะ route query ไปยัง connection ที่สอดคล้องโดยอัตโนมัติ:

  • เลือก stagingSELECT ทำงานกับ staging database
  • เลือก local → scenario เดิมทำงานกับฐานข้อมูลบนเครื่อง

คุณจึงไม่ต้องแก้ SQL หรือแก้ processor ทุกครั้งที่เปลี่ยน environment

เนื่องจาก credentials ถูกเก็บแบบ local จึงช่วยลดความเสี่ยงที่รหัสผ่าน production จะถูกแชร์ผ่าน cloud project ด้วย


รัน Database Test ใน CI ด้วย Apidog CLI

หลัง scenario ผ่านในแอปแล้ว ให้รันแบบ headless ใน CI เพื่อให้ทุก pull request ตรวจสอบทั้ง HTTP contract และข้อมูลในฐานข้อมูล

ติดตั้ง CLI และ login:

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

รัน 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 เช่น cli, html, junit

หากต้องการหลาย reporter:

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

ข้อสำคัญ: database connection เป็นข้อมูล local ดังนั้น CI runner ต้องมี configuration ที่เข้าถึงฐานข้อมูลได้ด้วย

หากใช้ชุดข้อมูลหลายแถว ให้ดู การทดสอบแบบขับเคลื่อนด้วยข้อมูลด้วย Apidog CLI และหากต้องการรันตามเวลา ดู การตั้งเวลาการทดสอบ API ด้วย Apidog


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

ฐานข้อมูลใดใช้ฟรี และฐานข้อมูลใดต้องเสียเงิน?

MySQL, SQL Server 2014+, PostgreSQL และ Oracle อยู่ในแผนฟรี ส่วน ClickHouse, MongoDB และ Redis ต้องใช้แผนแบบเสียเงิน เริ่มทดสอบกับฐานข้อมูลฟรีได้โดย ดาวน์โหลด Apidog

ใช้ค่าจากฐานข้อมูลใน request ถัดไปได้หรือไม่?

ได้ เพิ่ม Post Processor แบบ Database Operation แล้วรัน SELECT จากนั้นใช้ Extract Result To Variable พร้อม JSONPath เช่น:

$[0].fulfillment_ref
Enter fullscreen mode Exit fullscreen mode

อ้างอิงใน request ถัดไปด้วย:

{{fulfillment_ref}}
Enter fullscreen mode Exit fullscreen mode

ดูแนวคิดการส่งค่าระหว่างขั้นตอนได้ที่ การส่งข้อมูลระหว่างขั้นตอนการทดสอบ

เพื่อนร่วมทีมจะได้รับ Database Connection ของฉันอัตโนมัติหรือไม่?

ไม่ ข้อมูล connection เก็บอยู่ในเครื่องของผู้ใช้แต่ละคนและไม่ sync กับ cloud สมาชิกทุกคนต้องตั้งค่าเอง ซึ่งช่วยป้องกัน credentials สำคัญไม่ให้ถูกเก็บในโปรเจกต์ที่แชร์ร่วมกัน

ทำไม MySQL 8 เชื่อมต่อไม่ได้?

MySQL 8 ใช้ caching_sha2_password เป็นค่าเริ่มต้น ซึ่งอาจบล็อก connection ได้ ลองเปลี่ยน user เป็น mysql_native_password:

ALTER USER ... IDENTIFIED WITH mysql_native_password;
Enter fullscreen mode Exit fullscreen mode

รัน stored procedure หรือตรรกะฐานข้อมูลซับซ้อนได้หรือไม่?

ไม่ได้ผ่าน graphical interface โดยรองรับคำสั่งมาตรฐาน เช่น SELECT, INSERT, UPDATE และ DELETE เป็นหลัก ควรแยก stored procedure หรือ logic ที่ซับซ้อนออกจาก database test step


สรุป

การ query ฐานข้อมูลทำให้ API test เปลี่ยนจาก “response ดูถูกต้อง” เป็น “ข้อมูลถูกบันทึกถูกต้องจริง”:

  1. ใช้ Pre Processor เพื่อ seed ข้อมูลตั้งต้น
  2. เรียก API ตาม flow ที่ต้องการทดสอบ
  3. ใช้ Post Processor เพื่อ query และ assert ข้อมูลจริง
  4. extract ค่าจากฐานข้อมูลเพื่อเชื่อม request ถัดไป
  5. แยก connection ตาม environment เพื่อป้องกันการทดสอบผิดฐานข้อมูล

เริ่มจาก scenario ง่ายที่สุด: ดาวน์โหลด Apidog, เชื่อม MySQL กับฐานข้อมูล dev และเพิ่ม Post Processor หนึ่งตัวเพื่ออ่านแถวที่ endpoint เพิ่งสร้าง

Top comments (0)