การเขียนสคริปต์ทดสอบแบบอัตโนมัติเป็นเรื่องง่าย การเขียนสคริปต์ที่ยังคงมีประโยชน์หลังจากหกเดือนต่างหากที่เป็นเรื่องยาก สคริปต์ทดสอบจำนวนมากถูกเขียนขึ้น รันผ่านเพียงครั้งเดียว แล้วก็เสื่อมสภาพไปเงียบๆ แตกหักเมื่อมีการเปลี่ยนแปลงที่ไม่เกี่ยวข้อง ยืนยันผลลัพธ์ที่ไม่สำคัญ และฝึกให้ทีมงานละเลยการสร้างที่ล้มเหลว สคริปต์ทดสอบที่ดีจะต้องมีความแม่นยำ แยกส่วน และทนทาน
คู่มือนี้ครอบคลุมถึงว่าสคริปต์ทดสอบอัตโนมัติคืออะไร โครงสร้างที่ทำให้สคริปต์น่าเชื่อถือ สองวิธีในการเขียนสคริปต์ทดสอบ API และการสร้างทีละขั้นตอนใน Apidog
สคริปต์ทดสอบอัตโนมัติคืออะไร
สคริปต์ทดสอบอัตโนมัติคือชุดคำสั่งที่กำหนดไว้ สามารถทำซ้ำได้ ซึ่งจะทดสอบส่วนหนึ่งของซอฟต์แวร์ของคุณและตรวจสอบผลลัพธ์ โดยไม่ต้องให้มนุษย์ดำเนินการตามขั้นตอน สคริปต์จะส่งอินพุต ดำเนินการ และเปรียบเทียบผลลัพธ์กับสิ่งที่คาดหวัง ถ้าตรงกันก็จะผ่าน ถ้าไม่ตรงก็จะล้มเหลวและรายงานเหตุผล
สคริปต์ทดสอบคือรูปแบบที่สามารถดำเนินการได้ของ กรณีทดสอบ (test case) กรณีทดสอบจะอธิบายความตั้งใจ อินพุต การกระทำ และผลลัพธ์ที่คาดหวังในภาษาที่มนุษย์เข้าใจ สคริปต์จะแปลงความตั้งใจนั้นให้เป็นสิ่งที่เครื่องสามารถรันได้ทุกครั้งที่มีการคอมมิต หนึ่งกรณีทดสอบสามารถกลายเป็นหนึ่งสคริปต์ได้; สถานการณ์ทดสอบ (test scenario) มักจะกลายเป็นหลายสคริปต์ที่เชื่อมโยงกัน
คุณค่าทั้งหมดของสคริปต์ทดสอบอัตโนมัติคือการที่มันทำงานในลักษณะเดียวกันทุกครั้ง ซึ่งจะเป็นจริงได้ก็ต่อเมื่อสคริปต์ถูกเขียนให้เป็นแบบกำหนดได้ สคริปต์ที่ขึ้นอยู่กับลำดับการทำงานของสคริปต์อื่น หรือข้อมูลที่เหลือจากการรันครั้งก่อน ไม่ใช่ระบบอัตโนมัติที่น่าเชื่อถือ; มันเป็นภาระที่เปราะบางและไม่แน่นอน
โครงสร้างของสคริปต์ทดสอบที่น่าเชื่อถือ
สคริปต์ทดสอบที่เขียนไว้อย่างดีเกือบทุกอัน ไม่ว่าจะใช้ภาษาหรือเครื่องมือใด ก็จะมีโครงสร้างสี่ส่วนเหมือนกัน มักจะเรียกว่า Arrange-Act-Assert โดยมีการเพิ่มขั้นตอนการล้างข้อมูลเข้าไปด้วย
เตรียมการ (Arrange). ตั้งค่าทุกสิ่งที่การทดสอบต้องการ: ข้อมูลอินพุต, การยืนยันตัวตน, เงื่อนไขเบื้องต้นใดๆ สคริปต์ควรสร้างสถานะของตัวเองมากกว่าที่จะสมมติว่ามีอยู่แล้ว หากการทดสอบต้องการผู้ใช้ มันก็จะสร้างขึ้นมาใหม่ หรือใช้ฟิกซ์เจอร์ที่กำหนดไว้ ไม่ใช่สิ่งที่มีอยู่ในฐานข้อมูล
ดำเนินการ (Act). ดำเนินการเพียงหนึ่งการกระทำภายใต้การทดสอบ สคริปต์ที่ดีจะทดสอบพฤติกรรมเดียว การส่งคำขอ การเรียกใช้ฟังก์ชัน การเรียกใช้งานเหตุการณ์ นั่นคือการกระทำ และควรมีเพียงหนึ่งการกระทำต่อสคริปต์เท่านั้น
ยืนยันผล (Assert). ตรวจสอบผลลัพธ์เทียบกับสิ่งที่คาดหวัง นี่คือส่วนที่ทีมมักจะลงทุนน้อยไป สคริปต์ที่ยืนยันเพียงแค่ “ไม่มีข้อผิดพลาดเกิดขึ้น” หรือ “สถานะเป็น 200” แทบจะไม่ได้ทดสอบอะไรเลย การ ยืนยันผล ที่แข็งแกร่งจะตรวจสอบค่าจริง: เนื้อหาของคำตอบ (response body), โครงสร้าง (schema), ผลกระทบข้างเคียง (side effects), และเวลา (timing)
ล้างข้อมูล (Cleanup). ยกเลิกสิ่งที่สคริปต์สร้างขึ้น เพื่อให้สามารถรันใหม่ได้จากจุดเริ่มต้นที่สะอาด สคริปต์ที่ทิ้งข้อมูลทดสอบไว้เบื้องหลัง ในที่สุดจะเกิดความขัดแย้งกับตัวเองหรือกับสคริปต์อื่น
สามนิสัยที่แยกสคริปต์ที่ทนทานออกจากสคริปต์ที่เปราะบาง ทดสอบสิ่งเดียวต่อสคริปต์ เพื่อให้ความล้มเหลวมีสาเหตุที่ชัดเจนเพียงหนึ่งเดียว ทำให้สคริปต์เป็นอิสระต่อกัน เพื่อให้สามารถรันได้ในลำดับใดก็ได้ และยืนยันผลจากค่าที่เสถียร ไม่ใช่ข้อมูลที่ไม่แน่นอน เช่น ID ที่สร้างขึ้นหรือ timestamp ซึ่งจะทำให้สคริปต์ล้มเหลวโดยไม่มีเหตุผลที่แท้จริง
สองวิธีในการเขียนสคริปต์ทดสอบ API
สำหรับการทดสอบ API โดยเฉพาะ มีสองแนวทางทั่วไป และเหมาะสำหรับทีมที่แตกต่างกัน
แนวทาง Code-first คือการเขียนสคริปต์ทดสอบในภาษาโปรแกรมทั่วไป ใน Python หมายถึงเฟรมเวิร์กอย่าง pytest บวกกับไลบรารี HTTP; ใน JavaScript คือ test runner บวกกับ fetch คุณเขียนคำขอ การยืนยันผล และการตั้งค่าเป็นโค้ดจริง และสคริปต์จะอยู่ใน repository ของคุณควบคู่ไปกับแอปพลิเคชัน
แนวทางนี้ให้การควบคุมโปรแกรมอย่างเต็มที่ ตรรกะที่ซับซ้อน, ฟิกซ์เจอร์แบบกำหนดเอง, และการยืนยันผลที่ไม่ปกติ ล้วนเป็นเพียงโค้ด ข้อเสียคือทุกสคริปต์เป็นโค้ดที่คุณเขียนและดูแลรักษา ทีมงานต้องมีทักษะทางภาษา และโค้ดพื้นฐานจำนวนมาก, การจัดการการยืนยันตัวตน, การสร้างคำขอ, การแยกวิเคราะห์คำตอบ, จะถูกเขียนซ้ำในสคริปต์ต่างๆ เหมาะสำหรับทีมวิศวกรที่ต้องการให้การทดสอบมีเวอร์ชันพร้อมโค้ด และสะดวกใจที่จะดูแลรักษาสิ่งเหล่านั้น
แนวทางแบบภาพ (Visual approach) สร้างสคริปต์ทดสอบในเครื่องมือทดสอบ API โดยเฉพาะ คุณกำหนดคำขอ เพิ่มการยืนยันผลด้วยการคลิก และเชื่อมโยงคำขอเข้ากับสถานการณ์ โดยไม่ต้องเขียนหรือดูแลรักษาโค้ดสคริปต์สำหรับกรณีทั่วไป เครื่องมืออย่าง Apidog ใช้แนวทางนี้
แนวทางนี้ช่วยลดโค้ดพื้นฐาน (boilerplate) และทำให้สคริปต์อ่านได้ง่ายสำหรับทุกคนในทีม ไม่ใช่แค่ผู้ที่รู้ภาษาเท่านั้น คุณยังคงต้องใช้โค้ดที่กำหนดเองสำหรับตรรกะที่หายากซึ่ง visual builder ไม่สามารถแสดงออกได้ เหมาะสำหรับทีมผสมผสาน, การทดสอบที่นำโดย QA, และใครก็ตามที่ต้องการชุดทดสอบที่ทำงานได้อย่างรวดเร็วโดยไม่ต้องมีโปรเจกต์สคริปต์มาเกี่ยวข้อง
ไม่มีแนวทางไหนที่ผิด คำถามที่สำคัญคือใครเป็นผู้ดูแลสคริปต์และควรอยู่ใน repository ของแอปพลิเคชันหรือไม่ สำหรับการทดสอบ API ส่วนใหญ่ แนวทางแบบภาพช่วยให้ได้ชุดทดสอบที่เชื่อถือได้ทำงานเร็วขึ้นโดยมีการบำรุงรักษาน้อยลง
การเขียนสคริปต์ทดสอบ API อัตโนมัติใน Apidog
นี่คือขั้นตอนทั้งหมดสำหรับการสร้างสคริปต์ทดสอบ API ที่ทนทานด้วยภาพ
ขั้นตอนที่ 1: กำหนดคำขอ (Define the request). นำ endpoint เข้าสู่ Apidog จากไฟล์ OpenAPI หรือกำหนดโดยตรง นี่คือขั้นตอนการเตรียมการ (Arrange); คำขอจะประกอบด้วยเมธอด, พาธ, เฮดเดอร์ และบอดี้
ขั้นตอนที่ 2: เพิ่มข้อมูลทดสอบ (Add the test data). ตั้งค่าอินพุตเพย์โหลดสำหรับกรณีที่คุณกำลังทดสอบ เพื่อครอบคลุมอินพุตจำนวนมากด้วยสคริปต์เดียว ให้แนบไฟล์ CSV หรือ JSON เพื่อให้สคริปต์ทำงานหนึ่งครั้งต่อหนึ่งแถว; การทดสอบที่ขับเคลื่อนด้วยข้อมูล (data-driven testing) จะแทนที่สคริปต์ที่เกือบจะเหมือนกันหลายสิบอันด้วยอันเดียว
ขั้นตอนที่ 3: เขียนการยืนยันผล (Write the assertions). นี่คือหัวใจสำคัญ เพิ่มการตรวจสอบด้วยภาพ: สถานะเท่ากับโค้ดที่คาดไว้, ฟิลด์สำคัญในบอดี้มีอยู่จริงและมีค่าที่ถูกต้อง, คำตอบเป็นไปตาม schema, เวลาตอบสนองอยู่ในงบประมาณ สำหรับกรณีที่เป็นลบ ให้ยืนยันรูปแบบข้อผิดพลาด ไม่ใช่แค่โค้ดความล้มเหลว หลีกเลี่ยงการยืนยันข้อมูลที่ไม่แน่นอน
ขั้นตอนที่ 4: เชื่อมโยงคำขอเข้ากับสถานการณ์ (Chain requests into a scenario). เวิร์กโฟลว์จริงมักจะครอบคลุมการเรียกใช้หลายครั้ง สร้างสถานการณ์ที่เข้าสู่ระบบ สร้างทรัพยากร อ่านกลับมา และลบออก โดยส่งค่าจากขั้นตอนหนึ่งไปยังอีกขั้นตอนหนึ่ง แต่ละขั้นตอนคือสคริปต์; เมื่อรวมกันจะทดสอบโฟลว์ที่สมบูรณ์
ขั้นตอนที่ 5: เพิ่มตรรกะสคริปต์ที่กำหนดเองเฉพาะเมื่อจำเป็น (Add custom script logic only where needed). สำหรับการตรวจสอบที่การยืนยันผลด้วยภาพไม่สามารถแสดงออกได้, ตรรกะแบบมีเงื่อนไข, ค่าที่คำนวณได้, การเปรียบเทียบข้ามคำขอ, ให้เพิ่ม JavaScript pre-processor หรือ post-processor เก็บสิ่งนี้ให้น้อยที่สุด; สคริปต์ส่วนใหญ่ไม่จำเป็นต้องใช้เลย
ขั้นตอนที่ 6: รันและอ่านรายงาน (Run it and read the report). ดำเนินการสถานการณ์ Apidog จะรันทุกสคริปต์ ประเมินผลการยืนยันทุกรายการ และรายงานการตรวจสอบที่ล้มเหลวอย่างแม่นยำ พร้อมแสดงค่าที่คาดหวังและค่าจริงควบคู่กันไป
ขั้นตอนที่ 7: ทำให้การรันเป็นอัตโนมัติ (Automate the run). เชื่อมโยงสถานการณ์เข้ากับ CI/CD เพื่อให้ทำงานทุกครั้งที่มีการคอมมิต สคริปต์ทดสอบที่ทำงานเมื่อมีคนจำได้เท่านั้นไม่ใช่ระบบอัตโนมัติที่แท้จริง ดาวน์โหลด Apidog เพื่อสร้างสถานการณ์แรกของคุณ
การรักษาสคริปต์ทดสอบให้แข็งแรง
ชุดทดสอบคือสิ่งที่เคลื่อนไหวเปลี่ยนแปลงได้ สคริปต์ที่สมบูรณ์แบบในตอนที่เผยแพร่จะล้าสมัยไปเมื่อ API มีการเปลี่ยนแปลง สามแนวปฏิบัติที่ทำให้ชุดทดสอบน่าเชื่อถือ
อัปเดตสคริปต์พร้อมกับการอัปเดต API ไม่ใช่หลังจากนั้น เมื่อสัญญาของ endpoint เปลี่ยนแปลง สคริปต์ก็ควรเปลี่ยนใน commit เดียวกัน สคริปต์ที่ยืนยัน schema เก่าจะล้มเหลวด้วยเหตุผลที่ผิด และบ่อนทำลายความน่าเชื่อถือของสคริปต์อื่นๆ ทุกรายการ
ถือว่าสคริปต์ที่ทำงานไม่แน่นอนเป็นข้อผิดพลาดจริง สคริปต์ที่ผ่านส่วนใหญ่แย่กว่าการไม่มีสคริปต์เลย เพราะมันสอนให้ทีมรู้ว่าสีแดงไม่ได้หมายความว่าเสีย ค้นหาสาเหตุ ซึ่งมักจะเป็นสถานะที่ใช้ร่วมกันหรือการสันนิษฐานเรื่องเวลา และแก้ไขมัน
ตรวจสอบสคริปต์เหมือนกับโค้ดที่ใช้งานจริง สคริปต์ที่มีการยืนยันผลที่อ่อนแอ การตรวจสอบแค่สถานะ 200 เท่านั้น จะแสดงผลเป็นสีเขียวและให้ความรู้สึกปลอดภัยในขณะที่แทบไม่ได้ทดสอบอะไรเลย ผู้อ่านคนที่สองจะสังเกตเห็นสิ่งนั้นได้
คำถามที่พบบ่อย
กรณีทดสอบ (test case) และสคริปต์ทดสอบ (test script) แตกต่างกันอย่างไร? กรณีทดสอบจะอธิบายความตั้งใจในภาษาที่มนุษย์เข้าใจ, อินพุต, การกระทำ, ผลลัพธ์ที่คาดหวัง สคริปต์ทดสอบคือเวอร์ชันที่สามารถดำเนินการได้ซึ่งเครื่องจะรัน กรณีคือแผน; สคริปต์คือการนำไปปฏิบัติ
ฉันจำเป็นต้องรู้วิธีเขียนโค้ดเพื่อเขียนสคริปต์ทดสอบอัตโนมัติหรือไม่? ไม่จำเป็นสำหรับการทดสอบ API ด้วยเครื่องมือแบบภาพ ใน Apidog คุณสามารถสร้างคำขอ, การยืนยันผล, และสถานการณ์ด้วยการคลิก และเขียนโค้ดเฉพาะสำหรับตรรกะที่ไม่ธรรมดาเท่านั้น เฟรมเวิร์กแบบ Code-first จำเป็นต้องมีทักษะทางภาษา
ทำไมสคริปต์ทดสอบของฉันถึงล้มเหลวอยู่เสมอ? สาเหตุทั่วไปคือการยืนยันผลจากข้อมูลที่ไม่แน่นอน, สคริปต์ที่ขึ้นอยู่กับสถานะของกันและกัน, และการไม่อัปเดตสคริปต์เมื่อ API เปลี่ยนแปลง แยกข้อมูลทดสอบ, ทำให้สคริปต์เป็นอิสระต่อกัน, และอัปเดตสคริปต์ตามสัญญา
สคริปต์ทดสอบหนึ่งอันควรมีการยืนยันผลกี่รายการ? เพียงพอที่จะตรวจสอบผลลัพธ์ได้อย่างแท้จริง โดยปกติคือสถานะ, ฟิลด์สำคัญในบอดี้, schema, และเวลา การยืนยันสถานะโค้ดเพียงอย่างเดียวน้อยเกินไป; มันจะผ่านทั้งที่คำตอบผิดพลาด
สคริปต์ทดสอบควรอยู่ใน repository ของแอปพลิเคชันหรือไม่? ด้วยแนวทาง code-first โดยปกติแล้วใช่ เพื่อให้การทดสอบมีเวอร์ชันพร้อมโค้ด ด้วยเครื่องมือแบบภาพ สคริปต์จะอยู่ในแพลตฟอร์มการทดสอบและซิงค์กับคำจำกัดความของ API แทน ทำได้ทั้งสองอย่าง; ความสอดคล้องมีความสำคัญมากกว่าตัวเลือก
ฉันจะเขียนสคริปต์ทดสอบก่อนที่ API จะถูกสร้างขึ้นได้อย่างไร? เขียนมันโดยอ้างอิงจากการออกแบบ API หากคุณมีข้อกำหนด OpenAPI คุณสามารถกำหนดคำขอและการยืนยันผลจากมัน จากนั้นรันกับ mock server จนกว่า endpoint จริงจะพร้อมใช้งาน สคริปต์จะพร้อมใช้งานทันทีที่การนำไปใช้งานเสร็จสมบูรณ์
สคริปต์ทดสอบ (test script) และชุดทดสอบ (test suite) แตกต่างกันอย่างไร? สคริปต์ทดสอบจะดำเนินการตรวจสอบหนึ่งรายการ ชุดทดสอบคือการรวบรวมสคริปต์ที่จัดกลุ่มไว้เพื่อทำงานร่วมกัน ซึ่งมักจะครอบคลุม API หรือฟีเจอร์ทั้งหมด ชุดทดสอบช่วยจัดระเบียบชุดสคริปต์ที่เพิ่มขึ้น และช่วยให้คุณสามารถครอบคลุมการทดสอบในวงกว้างด้วยคำสั่งเดียว
สคริปต์ทดสอบอัตโนมัติควรมีความยาวเท่าใด? สั้นที่สุดเท่าที่จะทำได้ โดยยังคงทำครบทั้งสี่ส่วน: จัดเตรียม, ดำเนินการ, ยืนยันผล, และล้างข้อมูล หากสคริปต์ยาวเกินไป มักจะกำลังทดสอบมากกว่าหนึ่งสิ่งและควรแบ่งแยก หนึ่งพฤติกรรมต่อหนึ่งสคริปต์ช่วยให้การวินิจฉัยความล้มเหลวเป็นเรื่องง่าย
