[ลองใช้] Data-Driven Tests บน Robot Framework ด้วย Test Template
เนื่องจากเมื่อวันศุกร์ที่ผ่านมา ได้มีโอกาสแชร์ความรู้เรื่องเกี่ยวกับ Robot Framework แบบหลักสูตรเร่งด้วยใน 3 ชม แล้วมีคำถามนึง ที่ผมมองว่าน่าจะเป็นคำถามที่หลาย ๆ คนก็สงสัยเวลาที่เราทำ Automation Test ด้วย Robot Framework น่าจะต้องเจอเหมือนกัน คือ ถ้าเรามี Test Scenarios ที่เป็น End-To-End หลาย ๆ อัน เราจะสามารถทำยังไงได้บ้างที่ไม่ต้องเขียนเยอะ ๆ หรือเราจะดูแลรักษามันยังไงต่อ ซึ่งสำหรับผมแล้ว ถ้าจะตอบแบบกำปั้นทุบดินเลยก็คือ ก็อย่าทำให้มันมีเยอะ ๆ สิ เพราะการที่เรามี Scenarios ที่เป็น End-To-End เยอะ ๆ นั่นหมายถึงเราต้องใช้เวลาในพัฒนา Script เยอะขึ้นตาม แถมถ้ายิ่งเรามีเยอะเท่าไหร่ ระยะเวลาของการรันเพื่อทดสอบแบบ Regression Test ก็จะยิ่งยาวมากขึ้นเท่านั้น นั่นยิ่งจะทำให้เรารู้ตัวได้ช้ามาก ๆ ว่าการเปลี่ยนแปลงที่เกิดขึ้นจากความต้องกรที่เปลี่ยนไป มันกระทบกับความต้องการเดิมหรือเปล่า นี่ยังไม่นับว่าถ้า Test Script เยอะ ๆ แถมเขียนไว้ไม่เป็นระเบียบ มีซับซ้อน ในระดับที่ซับซ้อนมาก ๆ เวลาที่จะปรับแก้ Test Scripts ทีก็ต้องงม ต้องอ่าน ต้องทำความเข้าใจ ก่อนที่จะมีการแก้ ยิ่งทำให้เสียเวลาเข้าไปอีก เพราะฉะนั้นหลักการนึงของการทำ Test Automation คือพยายามทำให้ Test แบบ End-To-End มีอยู่น้อยที่สุด แล้วผลักการทดสอบลงไปใน Area ที่อยู่ต่ำลงไป เช่น Integration Test หรือ ให้ดีที่สุดคือผลักลงไปที่ Unit Test ให้ได้มากที่สุด นั่นเอง
แต่ถ้าเรามีปรับวิธีการทดสอบให้อยู่ในระดับที่ตำ่ลงไปในระดับนึงแล้ว ก็ยังพบว่าการทดสอบแบบ End-To-End ที่ทำยังมีจำนวนที่เยอะอยู่ เราสามารถใช้ Technique อื่น ๆ มาเพื่อช่วยลดความซับซ้อน และซ้ำซ้อน ของ Code ที่อยู่ใน Test Script ได้ ซึ่งวันนี้ผมเลยลองเอา Technique ที่ชื่อว่า Data Driven Tests มาลองเล่าให้ฟังดู ผ่าน Test Template ของ Robot Framework
ทำไมต้อง Test Template
หนึ่งในปัญหาของการเขียน Test Cases ใน Robot Framework ที่ทุกคนมักจะเจอหลังจากที่พัฒนามันมาได้สักพักแล้ว ก็คือ ความซับซ้อนของตัว Test Script ซึ่งยากต่อการทำความเข้าใจมากขึ้นเรื่อย ๆ ยิ่งทำความเข้าใจยากขึ้นก็ยิ่งใช้เวลากับการดูแลรักษามากขึ้น ซึ่งผิดกับหลักการสำคัญของการเอาภาษาที่เป็น Dynamic แบบนี้มาใช้ในการเขียน Test Script เพราะเป้าหมายหลักของการเขียน Robot Framework คือสร้าง Test Script ให้สามารถสื่อสารกับลูกค้าให้ได้ตรงกับ ภาษาของเขาให้ได้มากที่สุด เพราะฉะนั้นเราจำเป็นที่จะต้อง ดูแลรักษา Test Script ของเราให้อ่านง่าย และยังคงความใกล้ชิดกับลูกค้าหรือ ผู้ใช้งานอยู่ตลอดเวลา ซึ่งปัญหาความซับซ้อน ที่เกิดขึ้นอาจจะเกิดจากหลาย ๆ ปัจจัยหนึ่งในนั้นคือความซ้ำซ้อน (Duplication) ของ Script ที่เราเขียน หนึ่งในทางเลือกที่เราสามารถทำได้คือการสร้าง Keywords เพื่อลดความซ้ำซ้อนดังกล่าว แต่การสร้าง Keywords เองก็มีข้อจำกัด เพราะฉะนั้นวันนี้จะขออนุญาตพาไปให้รู้จักกับ การต่อยอดเอา Keyword มาใช้ในลักษณะที่เป็น Data-Driven Tests ซึ่งใน Robot Framework เราเรียกมันว่า Test Template
Data Driven Tests คืออะไร
Data-Driven Testing หรือหลาย ๆ คนอาจจะรู้จักกันในชื่อ Table-Driven Testing หรือ Parameterized Testing คือ วิธีการในการทดสอบ Software โดยพยายาม อธิบายเงื่อนไขของการทดสอบนั้นให้อยู่ในรูปแบบของ ตารางของข้อมูลที่ใช้ในการทดสอบ ซึ่งข้อมูลในตารางจะประกอบไปด้วย ข้อมูลที่ป้อนเข้าระบบ รวมถึงผลลัพท์ที่จะได้จากการใช้งาน
ซึ่งถ้าเราลองจำลอง Test Cases ของการ Login ก็จะสามารถเขียนอธิบาย การทดสอบทั้งหมดในกรณี Login ผิดพลาด ในรูปแบบของตารางของข้อมูลได้คร่าว ๆ ดังนี้
จะเห็นว่า ถ้าเราสามารถอธิบาย Test Cases ของเราได้ในรูปแบบของตารางแบบนี้ จะทำให้ Test Cases ของเราอ่านเข้าใจได้ง่ายขึ้น แถมถ้าจะต้องแก้ไขเงื่อนไขในการทดสอบของแต่ละ Test Case ก็สามารถแก้ไขที่ข้อมูลในบรรทัดนั้นได้ทันที
ด้วยแนวคิดที่ทำให้ง่ายต่อการดูแลรักษา และการทำความเข้า Test Cases แบบนี้นี่เองจึงทำให้เครื่องมือที่ใช้ในการเขียน Test Script หลาย ๆ ตัว มักจะทำมาเพื่อให้รองรับการทำ Data-Driven Tests โดยใน Robot Framework เราจะเรียกวิธีการแบบนี้ว่า Test Template
เงื่อนไขในการใช้ Test Template
เพื่อให้เราสามารถแปลง Test Cases ที่เราเขียนไว้ ให้สามารถมาใช้ Test Template ได้ มีเงื่อนไขที่เราต้องรู้ดังนี้
- จะมี Keyword หลักได้เพียงอันเดียวในไฟล์นั้น
- ถ้า Keyword หลักที่ใช้เป็น Keyword ที่เราสร้างเอง ทุก ๆ Test Cases จะต้องใช้ Step หรือ Workflows เดียวกันทั้งหมด
- กรณีที่มี Agruments ไม่เหมือนกัน ต้องแยกไฟล์เทสออกจากกัน
- ทุก ๆ Test Cases ที่อยู่ในไฟล์นี้ ต้องใช้ Keyword หลักเดียวกัน ต่างกันแค่ Agruments ที่ใส่เข้าไปในแต่ละ Test Case
- ถ้าจะให้ดี Keyword นั้นควรจะอยู่ที่เดียวกับที่รัน Test เพื่อจะได้เห็นว่าแต่ละ Test Cases มี Steps/Workflows อะไรบ้าง (แยกก็ได้ ถ้ามีความจำเป็นจริง ๆ)
- ใส่ชื่อของตัวแปรไว้บนหัว Column เพื่อให้อ่านง่าย
ลดความซ้ำซ้อนผ่าน Keywords
ก่อนจะไปที่ Test Template กัน ผมขอให้ดูตัวอย่างของ Test ที่ซ้ำซ้อน กันก่อนนะครับ เพื่อจะได้เห็นภาพที่ชัดเจน โดยที่ในตัวอย่างนี้ เป็น Test Cases สำหรับการทดสอบ Login โดยผมยกมาเฉพาะกรณีที่ Login ไม่สำเร็จเท่านั้น (ปกติผมจะแยก Test Scenarios/Test Cases ของกรณีที่ทำงานสำเร็จ กับกรณีที่ทำงานไม่สำเร็จออกจากกัน เพราะ Step/Flow การทำงานมักจะไม่เหมือนกันอยู่แล้ว
) ซึ่งประกอบไปด้วย Test Cases จำนวน 6 เคส ดังตัวอย่างข้างล่าง
จาก Code ตัวอย่างเราจะเห็นว่าทั้ง 6 เคส มีขั้นตอนการทำงานเหมือนกันทั้งหมด (เข้าเงื่อนไขข้อที่ 2) ต่างกันก็แค่ข้อมูลที่ใส่เข้าไปในระบบ (ตรงกับเงื่อนไขข้อที่ 3) เพื่อทำการ Login เท่านั้น ให้ลองคิดว่าเราต้องดูแล Script ชุดนี้ต่อไป แล้วปรากฏว่า มีการเปลี่ยนแปลงเกี่ยวกับการ Login เช่น ต้องเพิ่ม หรือแก้ Step เราก็ต้องมาตามแก้ในทุก ๆ Test Cases ซึ่งคงไม่ค่อยดีเท่าไหร่ เพราะก็มีโอกาสที่เราจะแก้ หรือเพิ่ม Step เข้าไปไม่ครบได้ เพราะฉะนั้นเราสามารถเอา Step ของทุก ๆ Test Cases มาสร้างเป็น Keywords เดียว ตัวใหม่ (ตรงกับเงื่อนไขข้อที่ 1) ที่ชื่อว่าLogin ผิดพลาด จะต้องแสดงข้อความ Error
และให้รับ Arguments เข้ามา 3 ตัว คือ USER
, PASSWORD
และ ERROR_MESSAGE
ซึ่งจะได้เป็นตัวอย่าง Code ข้างล่างนี้
โอเคหล่ะ มาถึงตรงนี้ถ้าเกิดต้องมีการแก้ไข ก็สามารถแก้ที่ Keywords ที่ชื่อ Login ผิดพลาด จะต้องแสดงข้อความ Error
ได้เลย แต่ถ้าสังเกตุก็จะเห็นว่า Test Case ที่เราเขียนมาก็ยังดูอ่านยากหน่อย ๆ แถมในแต่ละ Test Cases ก็มีแค่ Step เดียวด้วน ๆ ดูไม่ค่อยส่วยงามเลย เพราะฉะนั้นเราลองมาปรับ Test Cases ของเราให้อ่านง่ายขึ้น โดยใช้ หลักกการ Data-Driven ดูแล้วกัน
ลองใช้ Test Template
ลองมาตรวจสอบ Test Cases ที่เราเขียนไว้ ตามเงื่อนไขก่อหน้านี้ ก็จะได้ว่า Keyword หลักของทุก ๆ Test Cases ของ Login ก็คือ Login ผิดพลาด จะต้องแสดงข้อความ Error
แถมยังใช้ Agruments ชุดเดียวกัน แถม Steps/Workflows ของการ Test ยังเหมือนกันอีกด้วย เพราะฉะนั้นเราก็สามารถแปลง มาใช้ Test Template
ใน Section *** Setting ***
และระบุชื่อของ Keywords หลักของเรา ได้ดังตัวอย่างข้างล่างนี้
คำอธิบาย
- บรรทัดที่ 2: กำหนดว่าเทสไฟล์นี้ จะให้ทำงานเป็นแบบ Test Template และจะใช้ Keyword หลักที่ชื่อ
Login ผิดพลาด จะต้องแสดงข้อความ Error
สำหรับทุก ๆ Test Cases - บรรทัดที่ 5–10: กำหนดชื่อของแต่ละ Test Case ให้อยู่ใน Column แรก (อยู่ใต้
*** Test Cases ***
) และให้เอา Agruments ต่าง ๆ มาใส่ใน Column ต่อ ๆ มา ซึ่งกรณีนี้มี Agruments จำนวน 3 ตัว ก็เอามาใส่แล้วแยก Column ไป - บรรทัดที่ 4: ด้านหลังของ
*** Test Cases ***
เราสามารถใส่ชื่องของ Agruments ที่ส่งไปยังแต่ละ Test Cases ในรูปแบบของหัวตาราง
เพื่อให้เราง่ายต่อการทำความเข้าใจ - บรรทัดที่ 13–18: ยังคง Keyword หลักไว้ใน File เดียวกัน เพื่อให้เราสามารถทำความเข้าใจขั้นตอนการของทดสอบ
สามารถใช้ Template ใน Test Cases ได้ (ไม่แนะนำ)
จริง ๆ แล้วการเขียน Test Template ของ Robot Framework ยังสามารถใช้ได้อีก 1 วิธี โดยการกำหนด [Template]
ภายใต้ชื่อ Test Cases ซึ่งทำให้เราสามารถสร้าง Test Template หลาย ๆ อันได้ในไฟล์เทสเดียว (แต่ขอยืนยันอีกครั้งว่าไม่แนะนำ
) ได้ แต่ส่วนตัวแล้วผมชอบที่จะแยกมากกว่า แถมผมยังหาทางใส่ชื่อ Test Case เข้าไปไม่ได้ด้วยก็เลยไม่ค่อยชอบเท่าไหร่ ยังไงก็สามารถดูได้ดังตัวอย่างด้านล่าง
ข้อควรระวังในการใช้ Data-Driven Tests
อย่างที่เราคุยกันมาแต่ต้น แนวคิดของ Data-Driven Test ถูกสร้างมาเพื่อ ลดความซ้ำซ้อนเพื่อให้เกิด Test Scirpt ที่เข้าใจง่าย ซึ่งมีผลให้ง่ายต่อการดูแลรักษาในภายหลัง เพราะฉะนั้นการจะใช้ Test Template เองก็ควรอยู่บนหลักการเดียวกันนั้น หลาย ๆ ครั้งที่ผมได้มีโอกาสพูดคุยกับคนที่ใช้ Robot Framework ก็จะเห็นเริ่มมีการใช้ Test Template กันบ้าง แต่เนื่องจาก Test Cases ที่ออกแบบมาไม่ได้เหมาะกับการอ่านทำความเข้าใจมากนัก เช่น ใช้ Test Template ด้วย Agruments จำนวนมาก ซึ่งสุดท้ายกลายเป็น ตารางของข้อมูลตกลงมายังบรรทัดอื่น ๆ ทำให้เสียความสามารถที่อ่านได้ง่ายของ Test Template ไป รวมถึงการที่พยายามจะใช้ Test Template มากเกินไป ทั้ง ๆ ที่ Steps/Workflows มีส่วนที่ต่างกัน กลายเป็นว่า ไปการพยายามเอาทุกอย่างไปรวมใน Keywords เดียวเป็นไปได้ยาก แต่ก็สวมหัวใจสิงห์ เขียน If-Else ใน Keywords เพื่อตรวจสอบ Agrument ที่เข้ามาเพื่อให้สามารถทำ Steps/Workflows ที่ต่างกันในแต่ละ Test Cases ซึ่งผมก็มองว่าเป็นการเพิ่มความซับซ้อนให้กับ Test มากจนเกินไป (เขียน Logic เยอะ ๆ ใน Test Script ไม่กลัว Bug เหรอ หรือว่าต้องเขียน Test มาทดสอบ If-Else ใน Test Script ไหมนะ 555+)
เพราะฉะนั้นหลาย ๆ ครั้งที่ผมมีโอกาส ผมมักจะแนะนำให้คนที่กำลังศึกษา หรือทำงานด้วย Robot Framework ให้ไปลองอ่าน Guide Line ของการเขียน Robot Framework ที่ดี ที่ชื่อว่า How to write good test case