EP.11 เธอคนนั้นคือฉันอีกคน (Stubs)

Warittaya W.
WeLoveBug dot Com
Published in
4 min readSep 13, 2023

เส้นทางสู่การเป็น Tester 🐞 Bootcamp by WeLoveBug (21–27 สิงหาคม 2566)

สัปดาห์ที่ 3 ของโปรเจคการเงินการธนาคาร ซึ่งขณะนี้ดำเนินการมาถึงขั้นตอนที่เรานั้นเตรียมของสำหรับ Sprint 1 เสร็จเรียบร้อยแล้ว ต่อไปจึงเป็นขั้นตอนของการเตรียมการทดสอบ โดยการทดสอบ Sprint นี้เราจะทำการทดสอบ Automation Test ด้วย Postman จึงจำเป็นอย่างยิ่งที่จะต้องมีการ Design API และจัดเตรียมข้อมูลขึ้นมาเพื่อใช้การทดสอบด้วย

Day 1 🗓️ 21 สิงหาคม 2566

สัปดาห์ยังคงเป็นการทำงานออนไลน์ออนใจ เริ่มต้นวันใหม่เช้านี้ด้วยการเข้าประชุมร่วมกับทีม DEV ในเรื่องของการ Design API ว่าหน้าจอไหนมีการร้องขอข้อมูลและส่งคืนข้อมูลกลับมาอย่างไรบ้าง จากการเข้าร่วมประชุมและจับประเด็นขั้นตอนในการออกแบบ API แต่ละเส้น สามารถสรุปขั้นตอนในการออกแบบได้ดังนี้

ขั้นตอนการ Design API

  1. ตรวจสอบว่า หน้าจอนั้นต้องมีการ Load ข้อมูลหรือไม่ ถ้าต้อง Load มีการ Load ข้อมูลใดและจากที่ไหนบ้าง
  2. หากตรวจสอบตามข้อ 1. แล้ว ต่อมาต้องทำการตรวจสอบแต่ละ Action ในแต่ละหน้าจอว่ามีการเชื่อมต่อ API หรือไม่และมีการเชื่อมต่อเมื่อใด เช่น เชื่อมต่อเมื่อทํารายการถึงหน้าจอนั้นหรือเชื่อมต่อเมื่อกดปุ่ม
  3. ในการเชื่อมต่อ API แต่ละ Action นั้น มีการส่งข้อมูลหรือค่าใดไปยัง API และ API มีการตอบสนองต่อข้อมูลที่ส่งไปหรือมีการส่งค่าใดคืนมาบ้าง

เมื่อเราได้ API ในแต่ละเส้นแล้ว ขั้นตอนต่อไปคือการนำ Data Test ที่เราเตรียมไว้แล้วนั้นไปหยอดลงใน Request Body และ Response Body ของแต่ละเส้น API ด้วยรูปแบบการเขียนแบบ JSON

JSON เป็นข้อมูลรูปแบบ Text ที่เก็บข้อมูลแบบ Key และ Value โดยการเขียนข้อมูลชนิด JSON มีรูปแบบคือ Field Name ที่ครอบด้วยเครื่องหมาย “ ”(double quote), เครื่องหมาย : (colon), value และอยู่ภายใต้เครื่องหมายปีกกา { } หรือ Object เสมอ

{"key": "value"}

สำหรับมือใหม่หัดเขียนอย่างเรา จำเป็นอย่างยิ่งที่จะต้องทำความรู้จักกับรูปแบบการเขียน Code ซึ่งพื้นฐานที่ต้องรู้ก่อนคือ การเขียนข้อมูลให้อยู่ในรูปแบบของ Array

“Array” คืออะไร

Array เปรียบเสมือนชั้นเก็บของที่จะเก็บของประเภทเดียวกันไว้ภายในชั้นเดียวกัน แบบเป็นลำดับ โดยลำดับการนับตำแหน่งของ Array จะเริ่มต้นที่ 0, 1, 2, 3, …

ยกตัวอย่างเช่น หากเราต้องการเก็บข้อมูลชื่อและอายุของนักเรียนจำนวน 3 คนให้อยู่ในรูปแบบของ Array สามารถเขียนได้ดังนี้

{
"student_name": ["Pee", "Nut", "Fahsai"],
"student_age": [5,10,13]
}

หากมีชุดของข้อมูลนักเรียนที่มากขึ้น เราสามารถจัดเรียงข้อมูลใหม่ ให้อยู่ในภายใต้ตัวแปรเดียวกันนั่นหรือภายใต้ชุดข้อมูของนักเรียน 1 คนได้ เช่น การเพิ่มข้อมูลที่อยู่ ซึ่งสามารถเขียนได้ดังนี้

{
"student_data": [
{
"student_name": "Pee",
"student_age": 5,
"address": {
"building": "เคซีพาร์ค",
"house_no": "189/222",
"moo":"2",
"road": "บางพลี-ตำหรุ",
"sub_district": "แพรกษาใหม่",
"district":"เมือง",
"province": "สมุทรปราการ",
"postal_code": "10280",
"country": "ประเทศไทย"
}
},
{
"student_name": "Nut",
"student_age": 10,
"address": {
"building": "ตึกหรู",
"house_no": "999/99",
"moo":"9",
"road": "เรียบมาก",
"subDistrict": "คลองเตยเหนือ",
"district":"วัฒนา",
"province": "กทม",
"postalCode": "10100",
"country": "ประเทศไทย"
}
},
{
"student_name": "Fahsai",
"student_age": 10,
"address": {
"building": "ชวนชื่นมทาวน์ ราชพฤกษ์",
"house_no": "999/99",
"moo":"",
"road": "",
"subDistrict": "ลำโพ",
"district":"บางบัวทอง",
"province": "นนทบุรี",
"postalCode": "11110",
"country": "ประเทศไทย"
},

}
]
}

ความแตกต่างระหว่าง Object กับ Array

Object มี Key และ Value เป็นส่วนประกอบ แต่ Array ประกอบด้วย Value เพียงอย่างเดียวและเป็นการเก็บข้อมูลในตัวแปรเดียว

สิ่งที่ได้เรียนรู้ในวันนี้

  1. ขั้นตอนการ Design API บนหน้าจอ
  2. การเชื่อมต่อ API บางเส้นไม่ได้ส่ง Request แต่เป็นเพียงการส่ง Data เพื่อเก็บไว้ในฐานข้อมูลเท่านั้น และต้องถามเสมอว่า Data ที่ส่งไปเก็บนั้นมีอะไรบ้าง
  3. การเขียน Request Body และ Response Body ในรูปแบบของ json ที่ประกอบไปด้วย “Key” : “Value”, ที่อยู่ภายใต้ { } object เดียวกันและรูปแบบของ Array
  4. การเก็บ Audit Log เป็นการเก็บประวัติและรายละเอียดการเข้าใช้งานเพื่อใช้ในการตรวจสอบหากเกิดความผิดปกติ โดยจะเก็บข้อมูลจากเครื่องที่เข้าใช้ เช่น ข้อมูล IP Address, User, Datetime, Status เป็นต้น

Day 2 🗓️ 22 สิงหาคม 2566

สวัสดีวันอังคารค่ะ การประชุมและการทำงานร่วมกับทีม Dev ในวันนี้ยังคงอยู่ในรูปแบบออนไลน์เช่นเดิม โดยยังคงอยู่กับประเด็นของการออกแบบ API Spec ซึ่งทางทีมมีการรีเช็คความถูกต้องและความเข้าใจของข้อมูลภายใน Request Body และ Response Body ที่เราได้จำลองขึ้นโดยอ้างอิงจาก Requirements และข้อมูล Data Test ที่เตรียมไว้ในแต่ละหน้าจอ UI

เนื่องจากในวันพรุ่งนี้มีการประชุมเพื่อเก็บ Requirements ของ Sprint 2 จึงจำเป็นอย่างยิ่งที่เราจะต้องศึกษา Flow ของ Feature ใน Sprint 2 และตั้งคำถามในจุดที่สงสัยเพื่อนำกลับไปถามเจ้าของความต้องการต่อไป

Day 3–4 🗓️ 23–24 สิงหาคม 2566

ในการเก็บ Requirements ของ Sprint 2 นั้นยังคงเป็นการขุดเซาะเจาะหาจาก WorkFlow ที่ทาง BA ได้มีการวิเคราะห์และจัดทำมาให้ และเมื่อจบพิธีกรรมแล้วสิ่งที่ต้องดำเนินการต่อไปคือ การออกแบบและสร้าง Test Case จากเงื่อนไขที่ได้จากพิธีกรรมขุดเซาะเจาะหา สำหรับ Test Case จะถูกแบ่งออกเป็น 3 ส่วนเช่นที่เคยทำ คือ

  1. Field Validate
  2. Test by Feature แบ่งออกเป็น Success Case, Alternative Case และ Optional Test
  3. E2E Test

ซึ่งเราจะสนใจและออกแบบทั้งฝั่งที่เป็น Business Conditions และ System Conditons ด้วย

เนื่องจาก Sprint 2 นี้มี Feature ที่เป็น Process ท้ายสุดของโปรเจค ซึ่งส่วนนี้มีการดึงข้อมูลที่ User ทำการกรอกในแต่ละ Feature ก่อนหน้าทั้งหมดทำให้เราต้องทำการ Mapping ข้อมูลจาก Feature นี้ว่า ข้อมูลในแต่ละส่วนที่ดึงมาแสดงผลนั้นมาจากการ Input ข้อมูลจากหน้า UI หรือ Process ไหนบ้าง

เนื่องจากวันศุกร์ยังคงเป็นการขุดเซาะเจาะหาความต้องการของ Feature ใน Sprint 2 จึงขออนุญาต Skip รายละเอียดไปยังวันถัดไปนะคะ ⏭️

Day 6–7 🗓️ 26–27 สิงหาคม 2566

เนื่องจากโปรเจคนี้ต้องมีการทำ Automation Test ด้วยจึงก่อให้เกิดหลักสูตรเร่งรัด ในหัวข้อ “การใช้ทำ Automation Test ด้วย Postman” ซึ่งจะต้องมีการจำลองตัวแทนของระบบจริงหรือตัวแทนของ Service ภายนอกที่เราต้องการยิงขึ้นมา โดยใช้วิธีการ Stub (หนึ่งในเทคนิค Test Double) ด้วยการเขียน Code ขึ้นมาเพื่อให้ได้ค่าอย่างใดอย่างหนึ่งเพื่อนำไปใช้งานต่อและแสดงผลลัพธ์ปลายทางได้เหมือนที่เราต้องการ

เราจะใช้ “Mountebank” เป็นเครื่องมือสำหรับสร้าง Stubs ดังตัวอย่างด้านล่าง

{
"imposters": [
{
"port": 8080,
"protocol": "http",
"name": "login",
"stubs": [
{
"predicates": [
{
"caseSensitive": true,
"deepEquals": {
"method": "POST"
}
},
{
"caseSensitive": true,
"deepEquals": {
"path": "/login"
}
},
{
"caseSensitive": true,
"equals": {
"body": {
"username": "Matthew",
"password": "@12345Mat"
}
}
}
],
"responses": [
{
"is": {
"statusCode": 200,
"body": {
"serviceCode": 0,
"serviceMessage": "",
"serviceDateTime": "",
"accessToken": ""
},
"_mode": "text",
"_proxyResponseTime": 451
}
}
]
}
]
}
]
}

จากข้างต้น จะเห็นได้ว่า Stubs ที่เราสร้างขึ้นจะประกอบด้วย

  1. “predicates” เป็นการจำลอง Spec ของ Service ที่เราจะยิงไปหา
  2. “response” เป็นข้อมูลหรือสิ่งที่เราต้องการให้ตอบกลับมา

ต่อมาเราจะทำการ Run Test ด้วยการยิง API บน Postman ไปยัง Stubs ที่เราได้สร้างไว้

ใช้คำสั่ง mb start — configfile ชื่อไฟล์.json
ทำการยิง API บน Postman ไปยัง Stubs หาก Test Results ที่ได้รับถูกต้อง จะแสดงผลลัพธ์เป็น PASS

ปอลิง. ในส่วนของ Postman เราเคยเขียนแนะนำโครงสร้างและการใช้ Postman เบื้องต้นไว้แล้ว สามารถเข้าไปส่องได้ที่ ➡️ EP.4 ได้หน้าอย่าลืมหลัง ได้ Success อย่าลืม Alternative ได้เลยค่าา

จากภาคทฤษฎีและภาคปฏิบัติในหลักสูตรเร่งรัดสำหรับการสร้าง Stubs และการทำ Automation Test ทำให้เรารู้สึกได้ว่า เราก็เก่งเหมือนกันนะเนี่ย 55555 🤪 ก่อนหน้านี้รู้สึกกลัวว่า น้องๆ และทีมจะเหนื่อยในการมานั่งสอนเรารึป่าว เนื่องจากจะต้องมีการเขียน Code ร่วมด้วย แต่พอได้ทำจริงๆ แล้วรู้สึกสนุกกับการได้ลงมือทำ อีกทั้งตอนนี้ยังมีความสนใจในด้านของการจำลองระบบจริงด้วย Test Double Techniques และสนใจการใช้งานของ Mountebank ด้วยว่ามันใช้ทำอะไรได้อีกบ้างหรือเราสามารถใช้ Tools ไหนในการสร้าง Stub หรือ Mock และเลือกใช้ Test Double Techniques ให้เหมาะสมกับประเภทของงานได้อย่างไร ทำให้ตอนนี้เริ่มศึกษาในสิ่งที่สนใจและอยากทำ นอกเหนือจากการฝึกฝนการออกแบบในด้านของ Test Design Techniques อีกด้วย

Photo by Vidar Nordli-Mathisen on Unsplash

หลักสูตรหรือประสบการณ์ต่อไปที่เราจะมาแชร์นั้น ฝากทุกท่านติดตามกันด้วยนะคะ สำหรับวันนี้ Have a good day ค่ะ ☀️

--

--