ขั้นตอนการทำ ATDD (Acceptance Test-Driven Development): ความแตกต่างจาก BDD/TDD และรูปแบบการนำไปใช้

บทนำ
ATDD (Acceptance Test-Driven Development) คือวิธีการที่กำหนด Acceptance Test ซึ่งได้มาจากความต้องการทางธุรกิจ (Business Requirements) ก่อนการลงมือพัฒนา และดำเนินการพัฒนาเพื่อให้ผ่านการทดสอบเหล่านั้น แนวคิดนี้เกิดขึ้นเพื่อป้องกันสถานการณ์ที่ว่า "เขียนเทสต์ไว้แล้ว แต่กลับมาพบความเข้าใจที่คลาดเคลื่อนในตัวความต้องการหลังจากปล่อยผลิตภัณฑ์ไปแล้ว"
ในบทความนี้ เราจะอธิบายขั้นตอนการนำ ATDD ไปปรับใช้ทีละขั้นตอนโดยผสมผสานเข้ากับ BDD และ TDD โดยมุ่งเน้นไปที่ผู้อ่านที่เป็น QA Engineer, ผู้รับผิดชอบด้าน Test Automation และ Lead ของทีม Agile Development ตั้งแต่การแปลง Acceptance Test ให้เป็นภาษาที่เข้าใจได้ในขั้นตอนการกำหนดความต้องการ ไปจนถึงวิธีการทำให้อัตโนมัติและนำไปรวมเข้ากับ CI/CD Pipeline การติดตามกระบวนการเหล่านี้ตามลำดับจะช่วยให้คุณเห็นภาพรวมของกลยุทธ์การทดสอบที่สามารถป้องกันความผิดพลาดของความต้องการ (Requirement gaps) โดยไม่ทำให้ประสิทธิภาพในการพัฒนาลดลง
ATDD คือวิธีการพัฒนาที่เปลี่ยนความต้องการทางธุรกิจให้เป็นรูปแบบของการทดสอบ เพื่อให้ผู้เกี่ยวข้องตกลงร่วมกันก่อนเริ่มการพัฒนา ตามคำนิยามของ ISTQB การทดสอบการยอมรับ (Acceptance Testing) ถูกจัดวางให้เป็นวิธีการยืนยันความครบถ้วนของความต้องการ หากส่งต่อความต้องการในรูปแบบภาษาธรรมชาติไปสู่การพัฒนาโดยตรง มักจะเกิดความคลาดเคลื่อนในการตีความระหว่างนักพัฒนากับฝ่ายธุรกิจ ซึ่งบ่อยครั้งที่ความคลาดเคลื่อนดังกล่าวจะปรากฏให้เห็นเป็นครั้งแรกในขั้นตอนการทดสอบการรวมระบบ (Integration Testing) หรือการทดสอบการยอมรับ ATDD จึงเป็นวิธีการที่มุ่งเน้นการตรวจพบความคลาดเคลื่อนในการตีความเหล่านี้ตั้งแต่ก่อนเริ่มลงมือเขียนโค้ด ในหัวข้อ H3 ถัดไป เราจะมาดูว่าแนวคิดนี้ถูกทำให้เป็นรูปธรรมในขั้นตอนการพัฒนาอย่างไร และมีความแตกต่างจากวิธีการแบบเดิมอย่างไรบ้าง
ขั้นตอนพื้นฐานของ ATDD: ความต้องการ → การทดสอบ → การพัฒนา
เมื่อพัฒนาฟีเจอร์ใหม่ กระบวนการจะเริ่มต้นจากการหารือเกี่ยวกับข้อกำหนด แต่หากเป็นการแก้ไขฟีเจอร์ที่มีอยู่เดิม กระบวนการจะเริ่มต้นจากการทบทวน Acceptance Test ที่มีอยู่ ดังที่ได้กล่าวไปในส่วนก่อนหน้า สิ่งที่สนับสนุน ATDD คือลำดับขั้นตอนที่ว่า "กำหนดข้อกำหนดให้ชัดเจนก่อนเริ่มเขียนโค้ด" ซึ่งความสำเร็จหรือความล้มเหลวของการดำเนินงานขึ้นอยู่กับว่าสามารถรักษาลำดับขั้นตอนนี้ไว้ได้หรือไม่ แม้ว่ากระบวนการจะแบ่งออกเป็น 3 ขั้นตอนหลัก แต่ขั้นตอนการกำหนดข้อกำหนดในระยะแรกนั้นคุ้มค่าที่จะใช้เวลามากที่สุด
ในขั้นตอนการกำหนดข้อกำหนด Product Owner, นักพัฒนา และ QA Engineer ทั้งสามฝ่ายจะหารือร่วมกันเพื่อเปลี่ยนข้อกำหนดทางธุรกิจให้เป็นเงื่อนไขการยอมรับ (Acceptance Criteria) ที่เป็นรูปธรรม การใช้โครงสร้างแบบ Given/When/Then ของ Gherkin ในขั้นตอนนี้จะช่วยป้องกันไม่ให้การดำเนินงานคืบหน้าไปทั้งที่เงื่อนไขยังคลุมเครือ ตัวอย่างเช่น ข้อกำหนดที่ว่า "หากล็อกอินล้มเหลวครบ 3 ครั้ง บัญชีจะถูกล็อก" เพียงแค่ระบุสถานะเริ่มต้นใน Given (บัญชีที่ยังไม่ถูกล็อก), การกระทำใน When (การล็อกอินล้มเหลว 3 ครั้ง) และผลลัพธ์ใน Then (การเปลี่ยนสถานะไปสู่การถูกล็อก) ก็จะช่วยลดความคลาดเคลื่อนในการตีความระหว่างนักพัฒนาและ QA ได้ ในทางกลับกัน หากข้ามขั้นตอนนี้ไปแล้วดำเนินงานด้วยแนวคิดที่ว่า "เอาประมาณนี้ไปก่อน" มักจะนำไปสู่การพบเงื่อนไขที่ตกหล่นในขั้นตอนการออกแบบการทดสอบในภายหลัง ซึ่งมักจะทำให้ต้องกลับไปเริ่มหารือกันใหม่ตั้งแต่ต้น
ในขั้นตอนการออกแบบการทดสอบ เราจะเปลี่ยนเงื่อนไขการยอมรับที่ตกลงกันไว้ให้เป็น Acceptance Test ที่สามารถรันได้ เครื่องมือที่ได้รับการแนะนำในเอกสารอย่างเป็นทางการของ Cucumber มีจุดเด่นคือสามารถนำข้อกำหนดที่เขียนด้วยภาษาทั่วไปมาใช้เป็นแบบทดสอบที่รันได้โดยตรง โดยการทดสอบจะต้องถูกสร้างขึ้นก่อนโค้ดที่ใช้จริงและเริ่มต้นจากสถานะที่ทดสอบไม่ผ่าน
ขั้นตอนการนำไปใช้งาน (Implementation) นั้นเรียบง่ายกว่า โดยนักพัฒนาจะเขียนโค้ดโดยมีเป้าหมายเพียงเพื่อให้ผ่าน Acceptance Test เท่านั้น หากการทดสอบผ่านก็ถือว่าข้อกำหนดได้รับการตอบสนองแล้ว ทำให้สามารถตรวจพบความคลาดเคลื่อนระหว่างข้อกำหนดและการนำไปใช้งานจริงได้ตั้งแต่เนิ่นๆ การที่สามารถชดเชยการขาดมุมมองทางธุรกิจซึ่งยากที่จะตรวจพบได้ด้วย Unit Test เพียงอย่างเดียวนั้น เป็นเพราะลำดับขั้นตอนที่คิดย้อนกลับจากการทดสอบไปสู่ข้อกำหนดนั่นเอง
ความแตกต่างจากวิธีการทดสอบแบบดั้งเดิม
ในวิธีการทดสอบแบบดั้งเดิม ลำดับขั้นตอนที่พบได้ทั่วไปคือการที่นักพัฒนาเขียนโค้ดทดสอบหลังจากดำเนินการเขียนโปรแกรมเสร็จสิ้น หรือทีม QA อ่านเอกสารข้อกำหนดเพื่อสร้างกรณีทดสอบ (Test Case) ในลำดับเช่นนี้ "การทดสอบ" จะถูกจำกัดบทบาทไว้เพียง "เครื่องมือตรวจสอบการทำงานของสิ่งที่พัฒนาไปแล้ว" เท่านั้น และไม่มีฟังก์ชันในการตรวจพบความคลุมเครือของตัวความต้องการ (Requirement) ตั้งแต่เนิ่นๆ ในหน้างานการรีวิวโค้ด เรามักพบเหตุการณ์ที่การทดสอบถูกเขียนขึ้นภายหลัง ทำให้เงื่อนไขการทดสอบถูกปรับเปลี่ยนตามความสะดวกของโค้ดที่เขียนไปแล้ว เช่น จากเดิมที่เคยระบุว่า "ค่าขอบเขต (Boundary value) 3 รายการนั้นเพียงพอ" แต่กลับลดลงเหลือ 2 รายการเพื่อให้สอดคล้องกับโครงสร้างเงื่อนไข (Branching structure) ของโค้ดโดยไม่รู้ตัว ซึ่งนี่ไม่ใช่เรื่องของการละเลยหน้าที่ของใคร แต่เป็นปัญหาที่ตัวลำดับขั้นตอนเอง ซึ่งส่งผลให้การทดสอบทำหน้าที่เป็นเครื่องมือในการสร้างความชอบธรรมให้กับสิ่งที่พัฒนาไปแล้ว
ATDD แตกต่างจากวิธีเดิมอย่างชัดเจนตรงที่การสลับลำดับขั้นตอน โดยกำหนดเงื่อนไขการยอมรับ (Acceptance criteria) ให้ชัดเจนก่อนเริ่มการพัฒนา ในอภิธานศัพท์ของ ISTQB ได้นิยามการทดสอบการยอมรับ (Acceptance testing) ไว้ว่าเป็น "การทดสอบอย่างเป็นทางการเพื่อตัดสินว่าระบบเป็นไปตามเกณฑ์การยอมรับหรือไม่" ซึ่งอาจกล่าวได้ว่า ATDD คือแนวคิดการออกแบบที่นำการทดสอบการยอมรับนี้มาเป็นจุดเริ่มต้นของการพัฒนา
ความแตกต่างอีกประการหนึ่งคือ "ผู้อ่าน" การทดสอบ โค้ดทดสอบแบบดั้งเดิมถูกเขียนขึ้นโดยมีสมมติฐานว่านักพัฒนาหรือวิศวกร QA จะเป็นผู้อ่าน แต่การทดสอบการยอมรับของ ATDD มุ่งเน้นไปที่การเขียนด้วยภาษาที่เรียบง่าย (Plain text) ซึ่งเจ้าของผลิตภัณฑ์ (Product Owner) หรือผู้รับผิดชอบจากฝ่ายธุรกิจก็สามารถอ่านเข้าใจได้ ความแตกต่างนี้ช่วยลดความเสี่ยงที่จะเกิดความเข้าใจในข้อกำหนดไม่ตรงกันซึ่งมักจะถูกค้นพบหลังจากที่การพัฒนาเสร็จสิ้นแล้ว
ตารางเปรียบเทียบ ATDD, BDD และ TDD: เกณฑ์การเลือกใช้งาน
ในการทำงานจริง คุณเคยลังเลหรือไม่ว่าจะเลือกใช้ ATDD, BDD หรือ TDD อย่างไรดี? หากให้ความสำคัญกับการสร้างข้อตกลงในข้อกำหนดทางธุรกิจ ควรเลือก ATDD หากเน้นการใช้ภาษากลางสำหรับสถานการณ์จำลอง (Scenario) ควรเลือก BDD และหากเน้นคุณภาพภายในของการพัฒนาซอฟต์แวร์ ควรเลือก TDD เป็นหลัก อย่างไรก็ตาม ในโครงการจริงมักพบการใช้งานทั้ง 3 วิธีร่วมกัน
เกณฑ์ในการตัดสินใจคือ "ใครมีส่วนร่วมและต้องการตรวจสอบอะไร" ATDD มุ่งเน้นไปที่ขอบเขตของการทดสอบและผู้ที่มีส่วนเกี่ยวข้อง จึงเหมาะสำหรับขั้นตอนที่ลูกค้า, QA และนักพัฒนาตกลงร่วมกันเกี่ยวกับเกณฑ์การยอมรับ (Acceptance Criteria) ล่วงหน้า BDD มีหัวใจสำคัญอยู่ที่รูปแบบการเขียนและวิธีการแบ่งปันข้อมูล โดยจะเลือกใช้เมื่อต้องการแชร์ข้อกำหนดร่วมกับผู้ที่ไม่ใช่วิศวกรผ่านรูปแบบ Gherkin ที่ใช้ "Given/When/Then" ส่วน TDD มีจุดตัดสินใจอยู่ที่จังหวะเวลาและหน่วยของการพัฒนา โดยจะถูกนำมาใช้เมื่อต้องการตรวจสอบตรรกะภายในระดับฟังก์ชันหรือคลาสก่อนเริ่มการพัฒนาจริง
เมื่อสรุปความสัมพันธ์ของทั้ง 3 วิธี ATDD มีจุดประสงค์เพื่อการตกลงเงื่อนไขการยอมรับโดยตรง ส่วน BDD มักถูกใช้เป็นเครื่องมือในการบันทึกเนื้อหาที่ตกลงกันไว้ในรูปแบบที่ใกล้เคียงกับภาษาธรรมชาติอย่าง Gherkin ทั้งสองจึงไม่ใช่สิ่งที่ขัดแย้งกันแต่เป็นสิ่งที่นำมาใช้ร่วมกันได้ สำหรับ TDD นั้นเป็นวิธีการที่วนลูป "Red-Green" ในหน่วยที่เล็กที่สุดของการพัฒนา จึงทำหน้าที่เป็นเลเยอร์ระดับล่างที่คอยตรวจสอบรายละเอียดภายในเพื่อให้เป็นไปตามเงื่อนไขการยอมรับที่ ATDD หรือ BDD ได้กำหนดไว้
ในทางปฏิบัติ สิ่งที่มักถูกมองข้ามมากที่สุดคือการที่ผู้มีส่วนเกี่ยวข้องทางฝั่งธุรกิจสามารถจัดสรรเวลาเพื่อเข้าร่วมสร้างกรณีทดสอบ (Test Case) ได้จริงหรือไม่ หากไม่สามารถเข้าร่วมได้ ขั้นตอนการตกลงข้อกำหนดของ ATDD มักจะกลายเป็นเพียงรูปแบบที่ว่างเปล่า และมีแนวโน้มที่จะกลายเป็นการใช้งานเพียง BDD หรือ TDD เท่านั้น ทีมที่ไม่สามารถจัดสรรเวลาสำหรับการสร้างข้อตกลงร่วมกันได้ หากฝืนนำ ATDD มาใช้ อาจเหลือเพียงเอกสารเกณฑ์การยอมรับทิ้งไว้ และส่งผลให้การตรวจสอบความสอดคล้องกับการพัฒนาจริงไม่สามารถทำงานได้อย่างมีประสิทธิภาพ
ขอบเขตและช่วงเวลาในการนำแต่ละวิธีไปใช้
การแบ่งประเภทตามระดับของสิ่งที่ทดสอบและช่วงเวลาที่ดำเนินการจะช่วยให้จัดระเบียบความคิดได้ง่ายขึ้น
ATDD เป็นวิธีการกำหนดเกณฑ์การยอมรับ (Acceptance Criteria) ตั้งแต่ขั้นตอนการกำหนดความต้องการ โดยมีขอบเขตครอบคลุมพฤติกรรมของระบบทั้งหมด จุดเด่นคือการใช้การทดสอบการยอมรับที่ตกลงร่วมกันระหว่างลูกค้า QA และนักพัฒนา เป็นเกณฑ์ตัดสินก่อนที่จะดำเนินการพัฒนาเสร็จสิ้น เนื่องจากเป็นการกำหนด "เงื่อนไขผ่าน" ก่อนการพัฒนา ช่วงเวลาที่ดำเนินการจึงเป็นช่วงหลังจากการกำหนดความต้องการเสร็จสิ้นและก่อนเริ่มเขียนโค้ด
BDD แม้จะมีส่วนที่ทับซ้อนกับ ATDD อยู่มาก แต่ขอบเขตจะถูกจำกัดให้แคบลงในระดับฟังก์ชันหรือระดับสถานการณ์จำลอง (Scenario) โดยทั่วไปจะใช้เครื่องมืออย่าง Cucumber เพื่อเขียนสถานการณ์จำลองในรูปแบบ Given/When/Then ด้วยภาษา Gherkin และเพิ่มหรือดำเนินการทดสอบตามสถานการณ์จำลองในแต่ละรอบการพัฒนา (Iteration) ช่วงเวลาที่ดำเนินการจะเกิดขึ้นซ้ำๆ ทุกครั้งที่มีการพัฒนาฟังก์ชัน
TDD มีขอบเขตเล็กที่สุด โดยจะตรวจสอบคุณภาพภายในของหน่วยการพัฒนา เช่น คลาสหรือเมธอด ช่วงเวลาที่ดำเนินการจะทำไปพร้อมกับการเขียนโค้ดและมีความถี่สูงที่สุด เนื่องจากเป็นการหมุนเวียนวงจรการเขียนเทสต์ก่อนการพัฒนา (Test-first) และการทำ Refactoring ในระดับฟังก์ชัน จึงถือเป็นการสะสมส่วนประกอบภายในเพื่อตอบโจทย์เงื่อนไขการยอมรับภายนอกที่ ATDD และ BDD กำหนดไว้
หากทำความเข้าใจว่าขอบเขตของทั้ง 3 วิธีมีลักษณะเป็นโครงสร้างซ้อนกัน โดยมี ATDD เป็นกรอบนอก BDD เป็นชั้นกลาง และ TDD เป็นรายละเอียดชั้นใน จะช่วยให้ตัดสินใจลำดับการนำไปใช้ได้ง่ายขึ้น หากไม่แน่ใจว่าควรเริ่มจากชั้นไหนเป็นอันดับแรก พื้นฐานที่ควรทำคือการกำหนดเงื่อนไขผ่านด้วย ATDD ที่เป็นกรอบนอกก่อน แล้วจึงเติมเต็มส่วนภายในด้วย BDD และ TDD ตามลำดับ
การเลือกตามทักษะของทีมและความยากในการนำไปใช้
หากสมาชิกในทีมคุ้นเคยกับรูปแบบ Gherkin หรือสคริปต์อัตโนมัติอยู่แล้ว การเริ่มต้นด้วย BDD จะทำได้ง่ายกว่า แต่สำหรับทีมที่กระบวนการกำหนดความต้องการ (Requirement Definition) และกระบวนการ QA ยังไม่พร้อม การเริ่มต้นจากการกำหนดเกณฑ์การยอมรับ (Acceptance Criteria) ของ ATDD จะช่วยลดความยากในการนำมาใช้งานได้มากกว่า
มักมีแนวโน้มที่จะให้ความสำคัญกับการนำเครื่องมือมาใช้ก่อน แต่ในความเป็นจริง การปรับกระบวนการสร้างความเห็นพ้องต้องกัน (Consensus Building) ภายในทีมให้ลงตัวนั้นมีประสิทธิภาพมากกว่า หากนำเครื่องมืออย่าง Cucumber มาใช้ก่อนโดยที่ลูกค้า QA และนักพัฒนายังไม่มีความเข้าใจตรงกันในเรื่องวิธีการเขียนหรือระดับความละเอียดของเกณฑ์การยอมรับ ก็จะทำให้การทดสอบกลายเป็นเพียงรูปแบบที่ไม่มีเนื้อหาได้ง่าย ในเอกสารของ ATDD Workshop เองก็ได้ระบุโครงสร้างที่เน้นการจัดเซสชันในรูปแบบการฝึกปฏิบัติ (Workshop) เป็นเวลา 180 นาที (Most Preferred) ซึ่งแสดงให้เห็นถึงความสำคัญของการจัดสรรเวลาเพื่อสร้างความเห็นพ้องต้องกันก่อนที่จะเริ่มใช้เครื่องมือ
มุมมองในการประเมินความยากง่ายของการนำมาใช้งานมีอยู่ 3 ประการหลัก ได้แก่ ทักษะการออกแบบการทดสอบ (Test Design) ว่ามีบุคลากรที่สามารถย่อยเกณฑ์การยอมรับให้เป็นสถานการณ์จำลอง (Scenario) ที่เป็นรูปธรรมได้หรือไม่, ทักษะด้านระบบอัตโนมัติ (Automation) ว่ามีนักพัฒนาที่สามารถใช้งานเฟรมเวิร์กอย่าง Cucumber, SpecFlow หรือ FitNesse ได้หรือไม่ และวัฒนธรรมการสร้างความเห็นพ้องต้องกัน (Consensus Building) ว่าลูกค้า QA และนักพัฒนามีพื้นที่ในการตรวจสอบความต้องการร่วมกันอย่างสม่ำเสมอหรือไม่
หากมีส่วนใดส่วนหนึ่งใน 3 ประการนี้ไม่พร้อมตั้งแต่ 2 ข้อขึ้นไป แนวทางที่สมเหตุสมผลคืออย่าเพิ่งตั้งเป้าหมายนำมาใช้ทั้งองค์กรในทันที แต่ควรเริ่มทดลองใช้ ATDD กับฟีเจอร์เพียงหนึ่งหน่วย เพื่อสั่งสมรูปแบบความสำเร็จ (Success Pattern) ภายในบริษัทก่อนที่จะขยายผลต่อไป
ขั้นตอนการทำ ATDD: กระบวนการนำไปใช้แบบเป็นลำดับขั้น
กระบวนการนำ ATDD มาใช้แบ่งออกเป็น 3 ขั้นตอน ได้แก่ การกำหนดความต้องการ (Requirement Definition), การทำระบบอัตโนมัติ (Automation) และการรันการทดสอบอย่างต่อเนื่อง (Continuous Test Execution) แต่ในทางปฏิบัติแล้ว ช่วงเวลาและแรงงานส่วนใหญ่จะหมดไปกับขั้นตอนแรกคือการกำหนดความต้องการ หากฝั่งธุรกิจและฝั่งพัฒนามีความเข้าใจไม่ตรงกันในขั้นตอนนี้ ต่อให้ระบบอัตโนมัติที่ทำออกมาจะซับซ้อนเพียงใดก็ไม่มีความหมาย ดังนั้น จึงควรให้ความสำคัญสูงสุดกับการเขียนเงื่อนไขการยอมรับ (Acceptance Criteria) ในรูปแบบ Given-When-Then และปรับจูนจนกว่าผู้เกี่ยวข้องทุกคนจะเห็นพ้องต้องกันด้วยภาษาเดียวกัน
สำหรับขั้นตอนการทำระบบอัตโนมัติและการรันการทดสอบอย่างต่อเนื่องนั้น หากกำหนดความต้องการไว้ชัดเจนแล้ว จะถือเป็นขั้นตอนที่สามารถดำเนินการได้ในเชิงกลไกเสียมากกว่า การนำไปปรับใช้กับ Test Framework ที่มีอยู่และรันผ่าน CI Pipeline อย่างต่อเนื่องนั้นเป็นกระบวนการที่แต่ละทีมจะมีความแตกต่างกันไม่มากนัก และสามารถมองได้ว่าเป็นการแปลงข้อตกลงที่สรุปไว้ในขั้นตอนการกำหนดความต้องการให้กลายเป็นโค้ดเท่านั้น การจัดสรรเวลาโดยไม่จำเป็นต้องทำให้ทุกขั้นตอน "สมบูรณ์แบบก่อนจะไปต่อ" แต่เน้นการให้เวลากับการกำหนดความต้องการให้เพียงพอ และค่อยๆ พัฒนาความแม่นยำในขั้นตอนการทำระบบอัตโนมัติเป็นต้นไปผ่านการทำซ้ำ (Iteration) จะช่วยให้การนำมาใช้งานเป็นไปอย่างราบรื่นและเป็นขั้นเป็นตอน
ขั้นตอนที่ 1: การกำหนดความต้องการและการออกแบบกรณีทดสอบ
ควรระบุเงื่อนไขการยอมรับ (Acceptance Criteria) ในช่วงเวลาใดและโดยใคร?
จุดเริ่มต้นของ ATDD ไม่ใช่การที่นักพัฒนาเริ่มเขียนเคสทดสอบเพียงลำพัง แต่คือการสนทนาสามฝ่ายระหว่างเจ้าของผลิตภัณฑ์ (Product Owner), วิศวกร QA และนักพัฒนา ในเอกสารประกอบการประชุมเชิงปฏิบัติการของ Agile Alliance ได้ระบุรูปแบบการจัดเซสชันแนะนำ ATDD ซึ่งรวมถึงการสนทนานี้ไว้ โดยใช้เวลา 180 นาที (แนะนำ) หรือ 90 นาที ซึ่งแสดงให้เห็นถึงความสำคัญของการจัดสรรเวลาให้เพียงพอสำหรับการกำหนดความต้องการ
สำหรับวิธีการดำเนินการ ขั้นแรกให้ผู้เกี่ยวข้องร่วมกันระบุ "เงื่อนไขที่ถือว่าเสร็จสมบูรณ์" (Definition of Done) สำหรับแต่ละ User Story จากนั้นจึงแยกเงื่อนไขดังกล่าวออกเป็นรูปแบบ Given/When/Then และเปลี่ยนสำนวนที่คลุมเครือให้เป็นค่าอินพุตและเอาต์พุตที่ชัดเจน หากละเลยขั้นตอนนี้ เคสทดสอบในขั้นตอนถัดไปมักจะกลายเป็นสิ่งที่ "ทำงานได้ แต่ไม่รู้ว่ารับประกันอะไร" นอกจากนี้ การระบุรูปแบบข้อยกเว้น (กรณีผิดปกติ/ค่าขอบเขต) อย่างน้อย 1 รายการขึ้นไป จะช่วยลดการแก้ไขงานย้อนหลังในขั้นตอนการพัฒนาได้
ในขั้นตอนนี้ ไม่จำเป็นต้องทำให้เคสทดสอบกลายเป็นโค้ดที่เข้มงวด นี่เป็นแนวคิดที่ Gojko Adzic ได้นำเสนอไว้ใน "Specification by Example" โดยมีจุดมุ่งหมายเพื่อสร้างข้อตกลงด้วยตัวอย่างที่เป็นรูปธรรมในภาษาธรรมชาติก่อน แล้วจึงปรับให้มีความละเอียดในระดับที่สามารถนำไปพัฒนาต่อได้
ในโครงการช่วงเริ่มต้นที่ความต้องการมีการเปลี่ยนแปลงบ่อยครั้ง การลงรายละเอียดเคสทดสอบมากเกินไปจะเพิ่มต้นทุนในการแก้ไข ในกรณีเช่นนี้ วิธีการที่เหมาะสมคือการกำหนดเฉพาะสถานการณ์หลัก (Main Scenario) ให้ชัดเจนก่อน แล้วค่อยเพิ่มการทดสอบค่าขอบเขตโดยละเอียดควบคู่ไปกับขั้นตอนการพัฒนาจริง
ขั้นตอนที่ 2: การสร้างสคริปต์อัตโนมัติสำหรับ Acceptance Test
สคริปต์อัตโนมัติที่เขียนขึ้นนั้น ใครอ่านก็เข้าใจความหมายตรงกันหรือไม่ นี่คือเกณฑ์ตัดสินขั้นสุดท้ายในขั้นตอนที่ 2
เงื่อนไขการยอมรับ (Acceptance Criteria) ที่แปลงเป็นภาษาในขั้นตอนที่ 1 นั้นเป็นเพียงพิมพ์เขียวเท่านั้น กระบวนการเปลี่ยนพิมพ์เขียวให้กลายเป็นอาคารที่ใช้งานได้จริงก็คือการสร้างสคริปต์อัตโนมัติในขั้นตอนที่ 2 นี้เอง
เมื่อนำเงื่อนไขที่จัดระเบียบด้วย Given/When/Then มาปรับใช้กับรูปแบบ Gherkin ที่ Cucumber เลือกใช้ จะทำให้สามารถรวมข้อกำหนด (Specification) ที่แม้แต่ผู้ที่ไม่ใช่เอนจิเนียร์ก็อ่านเข้าใจ เข้ากับโค้ดทดสอบได้เป็นหนึ่งเดียว ทาง Cucumber ได้อธิบายไว้ว่าเครื่องมือนี้คือ "เครื่องมือสำหรับอ่านข้อกำหนดที่ปฏิบัติงานได้จริงซึ่งเขียนด้วย plain text" โดยมีโครงสร้างพื้นฐานคือการเชื่อมโยงขั้นตอน Given/When/Then เข้ากับคำอธิบายที่ขึ้นต้นด้วยคีย์เวิร์ด Feature
การดำเนินการจะเริ่มจากการจัดระเบียบสถานการณ์ (Scenario) ตามหน่วยของ Feature และเริ่มจาก Story ที่มีความสำคัญสูงสุดก่อน โดยการเขียน Step Definition (โค้ดที่ทำงานจริง) ที่สอดคล้องกับแต่ละขั้นตอนของ Gherkin ด้วย Cucumber หรือ SpecFlow และเชื่อมโยงเงื่อนไขที่เกี่ยวข้องกับการทำงานของ UI เข้ากับเครื่องมือควบคุมอัตโนมัติอย่าง Selenium เป็นต้น การปล่อยให้ขั้นตอนที่ยังไม่ได้ดำเนินการแสดงผลล้มเหลวไว้ก่อน จะช่วยให้มองเห็นได้ทันทีว่าส่วนใดที่ยังไม่ได้ดำเนินการ
สิ่งที่ควรระวังคือ อย่าพยายามสร้าง Test Case ทั้งหมดให้เสร็จสิ้นตั้งแต่แรก การทำให้สถานการณ์ของ 1 Story เป็นอัตโนมัติ แล้วทำซ้ำขั้นตอนการรันและการแก้ไข จะช่วยลดการย้อนกลับไปแก้ไขงานในภายหลังได้ดีกว่า ในกรณีที่เลือกใช้เครื่องมืออย่าง FitNesse ที่จัดการการทดสอบในรูปแบบตาราง การกำหนดความสัมพันธ์กับ Step Definition ให้ชัดเจนตั้งแต่ต้น ถือเป็นกุญแจสำคัญที่จะช่วยให้การรันการทดสอบอย่างต่อเนื่องในขั้นตอนถัดไปมีความเสถียร
ขั้นตอนที่ 3: การพัฒนาและดำเนินการทดสอบอย่างต่อเนื่อง
หัวใจสำคัญของขั้นตอนที่ 3 คือวงจรที่เรียบง่าย กล่าวคือ หากสคริปต์อัตโนมัติล้มเหลว แสดงว่าการปรับใช้ (implementation) ยังไม่ผ่านเกณฑ์การยอมรับ (acceptance criteria) แต่หากสำเร็จ ก็สามารถดำเนินการต่อไปยังเกณฑ์การยอมรับถัดไปได้ การปรับใช้เพื่อการพัฒนา (Development implementation) มีโครงสร้างคล้ายกับวงจรการทดสอบหน่วย (unit test) ของ TDD ตรงที่เริ่มต้นจากการทำให้การทดสอบการยอมรับ (acceptance test) ที่สร้างขึ้นในขั้นตอนที่ 2 ล้มเหลวก่อน แล้วจึงเขียนโค้ดต่อไปจนกว่าการทดสอบจะผ่าน แต่จุดที่แตกต่างจาก TDD คือเป้าหมายของการทดสอบอยู่ในระดับของความต้องการทางธุรกิจ (business requirements)
ในระหว่างการปรับใช้ จะเกิดโครงสร้างแบบสองชั้นที่ทำงานร่วมกัน คือการตรวจสอบความถูกต้องของตรรกะภายในด้วยการทดสอบหน่วย ในขณะเดียวกันก็ตรวจสอบพฤติกรรมจากมุมมองของผู้ใช้ด้วยการทดสอบการยอมรับ กรณีที่การทดสอบหน่วยผ่านแต่การทดสอบการยอมรับล้มเหลวนั้นไม่ใช่เรื่องแปลก และความแตกต่างนั้นเองที่เป็นเบาะแสบ่งชี้ถึงความเข้าใจที่คลาดเคลื่อนในข้อกำหนดหรือการปรับใช้ที่ตกหล่นไป
สำหรับการทดสอบอย่างต่อเนื่อง (continuous testing) นั้น มีสมมติฐานว่าต้องมีระบบที่รันการทดสอบการยอมรับในสภาพแวดล้อม CI ทุกครั้งที่มีการเปลี่ยนแปลงโค้ด หากพึ่งพาการรันด้วยตนเอง ความถี่ในการทดสอบจะลดลงและมักทำให้การตรวจพบข้อผิดพลาดล่าช้า การรวม การทดสอบอย่างต่อเนื่อง เข้าไปใน CI pipeline จะช่วยให้มั่นใจได้ว่าเกณฑ์การยอมรับของแต่ละฟีเจอร์จะได้รับการตรวจสอบอยู่เสมอ
สิ่งที่ทีมมักจะพลาดในขั้นตอนนี้คือการตัดสินใจยุติการพัฒนาทันทีที่การทดสอบการยอมรับผ่าน ในความเป็นจริงแล้ว ต้องตระหนักว่าการทดสอบการยอมรับเป็นเพียงดัชนีชี้วัดว่า "ได้ปฏิบัติตามข้อกำหนดทางธุรกิจแล้วหรือไม่" เท่านั้น ส่วนการตรวจสอบด้านประสิทธิภาพและความปลอดภัยจำเป็นต้องดำเนินการแยกต่างหาก
รูปแบบการนำ ATDD ไปใช้: วิธีการตามขนาดของโปรเจกต์
วิธีการนำ ATDD มาใช้ให้เหมาะสมนั้นจะแตกต่างกันไปตามขนาดของทีม สำหรับทีมขนาดเล็ก การใช้งานแบบเบาโดยจำกัดเครื่องมือถือเป็นทางเลือกที่สมเหตุสมผล แต่สำหรับทีมขนาดกลาง จำเป็นต้องมีการวางแผนเพื่อขยายขอบเขตการทำงานอัตโนมัติแบบเป็นขั้นตอน ส่วนในองค์กรขนาดใหญ่ การบูรณาการเข้ากับ CI/CD pipeline จะเป็นปัจจัยชี้ขาดถึงผลลัพธ์ของการนำไปใช้งาน ต่อไปนี้คือรูปแบบการกำหนดค่าเฉพาะตามขนาดของทีมครับ
สำหรับทีมขนาดเล็ก: การตั้งค่าเครื่องมือขั้นต่ำ
หากต้องการเริ่มทำ ATDD ในทีมขนาดเล็ก ควรเริ่มต้นจากจุดไหนดี?
ในช่วงแรก หลายคนมักคิดที่จะใช้เฟรมเวิร์กเดียวกับ Unit Test ในการทำ Acceptance Test แบบอัตโนมัติ แต่ในความเป็นจริง การเริ่มจากการนำเครื่องมือที่รองรับรูปแบบ Gherkin อย่างเช่น "Cucumber" มาใช้หนึ่งตัว แล้วเขียนความต้องการลงในไฟล์ "Feature" จะได้ผลดีกว่า การจำกัดจำนวนเครื่องมือจะช่วยลดต้นทุนในการเรียนรู้ และช่วยให้สมาชิกทุกคนในทีมมีเวลาทำความคุ้นเคยกับการเขียนแบบ "Given/When/Then"
ตัวอย่างองค์ประกอบของทีมขนาดเล็กคือการใช้ "Cucumber" ร่วมกับ "JUnit" โดยแบ่งบทบาทหน้าที่คือ "JUnit" รับผิดชอบด้าน Unit Test และการตรวจสอบการทำงาน (Implementation) ส่วน "Cucumber" รับผิดชอบด้านการรันสถานการณ์จำลอง (Scenario) ของ Acceptance Test สำหรับทีมที่มีนักพัฒนาประมาณ 3-5 คน การใช้เครื่องมือเพียง 2 ชนิดนี้ก็เพียงพอที่จะเป็นสะพานเชื่อมจากความต้องการไปสู่การทดสอบได้อย่างมีประสิทธิภาพ
แม้เครื่องมือในรูปแบบ Wiki อย่าง "FitNesse" จะเป็นอีกหนึ่งทางเลือก แต่รูปแบบ Gherkin นั้นง่ายต่อการรีวิวร่วมกับฝั่งธุรกิจ ซึ่งตรงกับวัตถุประสงค์หลักของ ATDD ในการแบ่งปันความเข้าใจด้านความต้องการ แทนที่จะเพิ่มจำนวนเครื่องมือ การเพิ่มขั้นตอนการรัน Acceptance Test เข้าไปในสภาพแวดล้อม CI ที่มีอยู่เดิมเพียงขั้นตอนเดียว ก็ถือเป็นการทำระบบอัตโนมัติขั้นต่ำที่เพียงพอแล้ว ส่วนการตัดสินใจขยายขอบเขตออกไปทีละน้อยนั้น ให้พิจารณาเมื่อถึงระดับขนาดทีมที่ใหญ่ขึ้นในครั้งถัดไป
สำหรับโปรเจกต์ขนาดกลาง: การทำระบบอัตโนมัติแบบเป็นลำดับขั้น
เกณฑ์การตัดสิน: คือวิธีการรับมือกับการเพิ่มขึ้นของขนาดทีมและจำนวนฟังก์ชันการทำงาน
ในขณะที่โครงสร้างขนาดเล็กมีจุดประสงค์เพื่อสร้างความคุ้นเคยกับรูปแบบ Gherkin แต่ในโครงการขนาดกลางที่มีหลายทีมเพิ่มฟังก์ชันการทำงานไปพร้อมกันนั้น การจัดการความซ้ำซ้อนของชุดทดสอบและการจัดเตรียมระบบการรีวิวจะกลายเป็นประเด็นสำคัญ เมื่อไฟล์ Feature เพิ่มขึ้นตามจำนวนฟังก์ชัน หากไม่มีกฎการตั้งชื่อหรือกฎการติด Tag จะทำให้เกิดความซ้ำซ้อนของสถานการณ์จำลอง (Scenario) และความล้าสมัยได้ง่าย อีกทั้งยังทำให้เวลาในการรันการทดสอบยาวนานขึ้นด้วย
สำหรับการทำระบบอัตโนมัติแบบเป็นขั้นตอน วิธีที่มีประสิทธิภาพคือการเริ่มต้นจากการติด Tag ให้กับ Scenario ใน Cucumber และรันเฉพาะการทดสอบการยอมรับ (Acceptance Test) ที่มีความสำคัญสูงเป็นรายวัน แทนที่จะรันทุก Scenario ในทุกครั้ง ให้ใช้วิธีเริ่มจากส่วนที่มีความเสี่ยงต่อการเกิด Regression สูงก่อน แล้วจึงค่อยขยายขอบเขตออกไป
ในกรณีที่ใช้ SpecFlow ร่วมด้วย จะสามารถเชื่อมโยงกับการทำ Unit Test ในโครงการกลุ่ม .NET ได้ง่ายขึ้น และช่วยให้จัดเตรียมระบบที่นักพัฒนาสามารถตรวจสอบผลลัพธ์ของการทดสอบการยอมรับในระดับ Pull Request ได้สะดวก หากมีการรวมเครื่องมือควบคุมเบราว์เซอร์อย่าง Selenium เข้าไปในการทดสอบระดับ UI เนื่องจากเวลาในการรันมักจะยาวนาน การออกแบบโดยแยกการทดสอบผ่าน UI และการทดสอบระดับ API ออกจากกันจะช่วยลดภาระในการบำรุงรักษาได้
ในส่วนของการแบ่งบทบาทหน้าที่ หากใช้ระบบการแบ่งงานที่ QA Engineer เป็นผู้นำในการสร้าง Scenario และนักพัฒนาเป็นผู้รับผิดชอบในการเขียน Step Implementation จะมีแนวโน้มช่วยลดการโต้ตอบไปมาในการรีวิวลงได้
สำหรับองค์กรขนาดใหญ่: การรวมเข้ากับ CI/CD Pipeline
เมื่อหลายทีมพัฒนาไปพร้อมกัน การขนานการรันการทดสอบจะกลายเป็นโจทย์สำคัญ และหากมีความถี่ในการปล่อยซอฟต์แวร์สูง ลำดับการรันภายในไปป์ไลน์และการออกแบบเกต (gate design) ก็จะกลายเป็นประเด็นท้าทาย สำหรับองค์กรขนาดใหญ่ จำเป็นต้องสร้างระบบที่รวมการทดสอบการยอมรับ (Acceptance Test) เข้าเป็นส่วนหนึ่งของ CI/CD ไปป์ไลน์ เพื่อให้มีการรันโดยอัตโนมัติทุกครั้งที่มีการเปลี่ยนแปลงโค้ด
โดยเฉพาะอย่างยิ่ง รูปแบบที่เป็นตัวแทนคือการจัดการไฟล์ Feature ที่เขียนด้วย Cucumber หรือ SpecFlow ไว้ที่ศูนย์กลางในรีโพสิทอรี และกำหนดค่าให้ทริกเกอร์การทดสอบการยอมรับบางส่วนควบคู่ไปกับยูนิตเทสต์ ณ เวลาที่สร้าง Pull Request เนื่องจากเวลาในการรันจะเพิ่มขึ้นหากรันทุกสถานการณ์ในทุกครั้ง การควบคุมลำดับความสำคัญด้วย การติดแท็ก (Tagging) จึงเป็นสิ่งที่ต้องทำอย่างต่อเนื่อง โดยในทางปฏิบัติควรตั้งเกตสองระดับ คือรันเฉพาะการทดสอบการยอมรับระดับสโมค (Smoke Test) ในสาขาที่เป็น Release Candidate และรันทุกสถานการณ์ในสภาพแวดล้อม Staging ก่อนนำไปใช้จริง
ในกรณีที่ใช้งานร่วมกับ Selenium หรือเครื่องมือทดสอบ API การทำคอนเทนเนอร์ (Containerization) ให้กับสภาพแวดล้อมการรัน เพื่อให้สามารถจำลองสภาพแวดล้อมที่มีเงื่อนไขเดียวกันได้ทุกครั้งที่รันการทดสอบ จะช่วยให้แยกแยะสาเหตุความล้มเหลวที่เกิดจากความแตกต่างของสภาพแวดล้อมได้ง่ายขึ้น นอกจากนี้ การแสดงผลลัพธ์การทดสอบผ่านแดชบอร์ดและรักษาความสามารถในการติดตามว่าสถานการณ์ที่ล้มเหลวนั้นเชื่อมโยงกับความต้องการ (Requirement) ใด จะช่วยป้องกันไม่ให้ ความสัมพันธ์ระหว่างความต้องการและการทดสอบ เกิดความคลาดเคลื่อน ในระดับที่มีหลายทีมเกี่ยวข้อง จำเป็นต้องมีระบบที่ QA Lead คอยทบทวนกฎการตั้งชื่อและการจัดการแท็กอย่างสม่ำเสมอ
เครื่องมือหลักที่ใช้ใน ATDD และเกณฑ์การคัดเลือก
Q1. เครื่องมือที่เป็นตัวแทนสำหรับการทำ Acceptance Test Automation ใน ATDD มีอะไรบ้าง?
เครื่องมือที่เป็นตัวแทนได้แก่ Cucumber, SpecFlow และ FitNesse โดย Cucumber มีจุดเด่นที่สามารถอ่าน Specification ที่เขียนด้วยรูปแบบ Gherkin ซึ่งเป็นรูปแบบที่รันได้จริง และสามารถรัน Scenario ในรูปแบบ Given/When/Then ให้เป็น Test Code ได้ ส่วน SpecFlow จะมอบกลไกที่คล้ายกันสำหรับสภาพแวดล้อม .NET และ FitNesse จะใช้วิธีการที่แตกต่างออกไปโดยการเขียนเงื่อนไขการยอมรับ (Acceptance Criteria) ในรูปแบบตาราง
Q2. เงื่อนไขเบื้องต้นที่ควรตรวจสอบเมื่อเลือกใช้ Cucumber คืออะไร?
Cucumber จะรวบรวม Scenario ไว้ในหน่วยที่เรียกว่าไฟล์ Feature และประกอบด้วยคำสำคัญอย่าง Given/When/Then ในการนำมาใช้งานจำเป็นต้องตรวจสอบเวอร์ชันของภาษาในสภาพแวดล้อมการทำงาน ตัวอย่างเช่น เอกสารประกอบการประชุมเชิงปฏิบัติการของ Agile Alliance ได้ระบุโครงสร้างที่กำหนดให้ใช้ Java 1.5 ขึ้นไป ในโครงการจริงควรตรวจสอบเวอร์ชันที่รองรับจากเอกสารอย่างเป็นทางการล่วงหน้าตามภาษาที่ใช้และสภาพแวดล้อมในการ Build
Q3. เกณฑ์การเลือกเครื่องมือเปลี่ยนไปตามขนาดของทีมหรือไม่?
ใช่ เปลี่ยนไปตามขนาดของทีม ในทีมขนาดเล็กที่ใช้ .NET มักจะเลือกใช้ SpecFlow ส่วนในสภาพแวดล้อมที่ใช้ Java หรือสภาพแวดล้อมที่มีหลายภาษาผสมกันมักจะเลือกใช้ Cucumber ในกรณีของทีมที่ให้ความสำคัญกับการจัดระเบียบเงื่อนไขในรูปแบบตาราง FitNesse อาจจะเหมาะสมกว่า นอกจากนี้ ความง่ายในการบูรณาการเข้ากับโครงสร้าง CI/CD ที่มีอยู่ก็เป็นเกณฑ์ในการตัดสินใจเช่นกัน ส่วนการควบคุมลำดับความสำคัญด้วยการติด Tag ที่กล่าวถึงในส่วนก่อนหน้านี้ ทั้ง Cucumber และ SpecFlow ต่างก็รองรับเป็นมาตรฐานอยู่แล้ว
Q4. มีหนังสือหรือเอกสารที่ควรศึกษาควบคู่ไปกับเครื่องมือหรือไม่?
หนังสือเรื่อง "Specification by Example" เขียนโดย Gojko Adzic (สำนักพิมพ์ Manning, ปี 2011) ได้อธิบายแนวคิดในการเขียน Specification ของ Acceptance Test ด้วยตัวอย่างที่เป็นรูปธรรมอย่างเป็นระบบ ซึ่งมีคุณค่าในการอ้างอิงเพื่อทำความเข้าใจปรัชญาการออกแบบของ ATDD สามารถใช้เป็นเอกสารเพื่อเสริมมุมมองในเรื่องวิธีการสร้างฉันทามติเกี่ยวกับเงื่อนไขการยอมรับกับฝ่ายธุรกิจ ไม่ใช่เพียงแค่การใช้งานเครื่องมือเท่านั้น
Q5. ในทางปฏิบัติมีการใช้เครื่องมือหลายตัวร่วมกันหรือไม่?
ขึ้นอยู่กับกรณี ตัวอย่างเช่น การใช้ Cucumber ร่วมกับ Selenium สำหรับ Acceptance Test ในระดับ UI และใช้ JUnit สำหรับ Unit Test เป็นรูปแบบที่พบได้ทั่วไป นอกจากนี้ยังมีการออกแบบที่แยกเครื่องมือตามระดับชั้น เช่น การใช้เครื่องมืออื่นในการตรวจสอบระดับ API แต่เนื่องจากยิ่งเพิ่มเครื่องมือมากเท่าใด ต้นทุนในการบำรุงรักษาก็จะยิ่งสูงขึ้น ดังนั้นการพิจารณาโครงสร้างที่สามารถบริหารจัดการแบบรวมศูนย์ได้ด้วย Pipeline ของ CI/CD ที่มีอยู่ จึงเป็นเกณฑ์การตัดสินใจในทางปฏิบัติ
คำถามที่พบบ่อยเกี่ยวกับการนำ ATDD ไปใช้
เราจะสรุปประเด็นที่ผู้ปฏิบัติงานมักเกิดความสับสนเมื่อพิจารณาการนำ ATDD มาใช้ เช่น ช่วงเวลาที่เหมาะสมในการนำมาใช้, ความเป็นไปได้ในการปรับใช้กับโปรเจกต์ที่มีอยู่เดิม และขั้นตอนการใช้งานร่วมกับ BDD โดยจะอธิบายจุดตัดสินใจของทั้ง 3 ประเด็นต่อไปนี้อย่างเป็นรูปธรรม
ควรเริ่ม ATDD เมื่อใด และควรนำไปใช้ในขั้นตอนไหนของโปรเจกต์
เกณฑ์การตัดสิน: ยิ่งเริ่มในขั้นตอนการวางแผนก่อนที่ความต้องการ (Requirements) จะชัดเจนเท่าใด ก็ยิ่งเห็นผลลัพธ์ได้มากเท่านั้น หากนำมาใช้หลังจากที่การพัฒนาคืบหน้าไปแล้ว จำเป็นต้องจำกัดขอบเขตให้แคบลง
เนื่องจาก ATDD เป็นวิธีการที่กำหนดเกณฑ์การยอมรับ (Acceptance Criteria) ไว้ก่อนเริ่มลงมือพัฒนา จึงควรนำมาใช้ตั้งแต่ช่วงเริ่มต้นของขั้นตอนการกำหนดความต้องการ หรืออย่างน้อยที่สุดคือในช่วงการวางแผนรอบการทำงาน (Iteration) แรก การที่ Product Owner หรือผู้รับผิดชอบฝั่งธุรกิจเข้ามาร่วมตกลงเกณฑ์การยอมรับถือเป็นหัวใจสำคัญของ ATDD ซึ่งหากนำกระบวนการนี้มาแทรกในภายหลัง ประสิทธิภาพจะลดลง
สำหรับโครงการใหม่ การเริ่มสร้างสถานการณ์จำลอง (Scenario) ด้วยรูปแบบ Gherkin ตั้งแต่ Sprint แรกถือเป็นสิ่งที่เหมาะสม ในทางกลับกัน หากการกำหนดความต้องการเสร็จสิ้นและเริ่มการพัฒนาไปแล้ว การจำกัดขอบเขตไว้เฉพาะฟีเจอร์ใหม่ที่กำลังจะเริ่มทำหรือรายการใน Backlog ที่ยังไม่ได้พัฒนาถือเป็นจุดเริ่มต้นที่เป็นจริงได้มากที่สุด
จุดตัดสินใจคือ "มีฟีเจอร์ที่เกณฑ์การยอมรับยังไม่ชัดเจนอยู่หรือไม่" หากยังมีฟีเจอร์ที่ยังไม่ชัดเจนเหลืออยู่ ก็สามารถเริ่มจากจุดนั้นได้ แต่หากความต้องการทั้งหมดถูกพัฒนาไปแล้วและเกณฑ์การยอมรับมีอยู่เพียงโดยนัย (Implicit) จำเป็นต้องปฏิบัติตามขั้นตอนการนำมาใช้ภายหลังที่จะอธิบายต่อไป ในกรณีที่ทีมยังไม่คุ้นเคยกับกระบวนการของ ATDD แนวทางปฏิบัติที่จัดการได้ง่ายคือการเริ่มทดลองใช้กับฟีเจอร์ที่มีขอบเขตผลกระทบเล็กน้อย เพื่อสร้างรูปแบบการเขียน Acceptance Test และระบบการรีวิวให้มั่นคงเสียก่อน แล้วจึงค่อยๆ ขยายขอบเขตออกไปทีละน้อย
สามารถเพิ่ม ATDD เข้าไปในโปรเจกต์ที่มีอยู่เดิมได้หรือไม่
การปรับปรุงฟังก์ชันที่มีอยู่เดิมจะเป็นการนำไปใช้โดยจำกัดขอบเขตผลกระทบ ในขณะที่การนำไปใช้กับฟังก์ชันใหม่ที่จะเพิ่มเข้ามาในอนาคตจะช่วยให้เกิดการยอมรับได้ง่ายกว่า ซึ่งเป็นความแตกต่างที่สำคัญ การเพิ่มภายหลัง (Retrofitting) เปรียบเสมือนการเดินท่อในอาคารที่สร้างโครงสร้างเสร็จสมบูรณ์แล้ว ซึ่งจำเป็นต้องตัดสินใจเลือกจุดที่ไม่ต้องทุบผนัง
เมื่อนำ ATDD มาใช้ในโปรเจกต์ที่มีอยู่เดิม การเริ่มทำระบบอัตโนมัติของ "acceptance test" จากฟังก์ชันที่มีแผนจะพัฒนาใหม่ถือเป็นวิธีที่สมเหตุสมผลที่สุด หากย้อนกลับไปสร้างเกณฑ์การยอมรับ (acceptance criteria) ให้กับฟังก์ชันที่เคยพัฒนาไปแล้ว อาจทำให้พบความไม่สอดคล้องกันระหว่างโค้ดที่เขียนไว้กับข้อกำหนด ซึ่งจะส่งผลให้ต้นทุนในการแก้ไขงานเพิ่มสูงขึ้น การค่อยๆ เพิ่ม "acceptance test" จากการแก้ไขบั๊กที่มีความสำคัญสูงหรือฟังก์ชันที่มีการเปลี่ยนแปลงบ่อย จะช่วยให้สามารถขยายขอบเขตการใช้งานไปพร้อมกับการตรวจสอบความคุ้มค่าของการลงทุน (ROI) ได้
ในทางกลับกัน หากมี E2E test อยู่แล้ว การนำเทสต์เหล่านั้นมาเขียนใหม่เป็นสถานการณ์จำลองด้วย Gherkin syntax อาจช่วยลดต้นทุนในการย้ายระบบได้ ยิ่งโปรเจกต์ใดมีความสัมพันธ์ระหว่างโค้ดทดสอบกับความต้องการทางธุรกิจน้อยเท่าใด ปริมาณงานในช่วงเริ่มต้นของการเพิ่มภายหลังก็มักจะยิ่งสูงขึ้นเท่านั้น ดังนั้น การเริ่มจาก "การทดลองขนาดเล็ก" ในฟังก์ชันที่มีขอบเขตผลกระทบจำกัด แล้วค่อยขยายขอบเขตการใช้งานไปพร้อมกับการดูระดับความเข้าใจของทีมและความพร้อมของโครงสร้างพื้นฐานด้านระบบอัตโนมัติ จึงเป็นแนวทางที่จัดการได้ง่ายในหน้างานจริง
แนวทางการดำเนินงานเมื่อต้องนำ ATDD และ BDD ไปใช้พร้อมกัน
ATDD และ BDD ไม่ใช่วิธีการที่ขัดแย้งกัน แต่เป็นความสัมพันธ์ที่ใช้เกณฑ์การยอมรับ (Acceptance Criteria) ร่วมกัน หากพิจารณาที่จะนำมาใช้พร้อมกัน ควรเริ่มจากการกำหนดรูปแบบการเขียนสถานการณ์ด้วย Gherkin syntax ให้ชัดเจนก่อน แล้วจึงสร้างกระบวนการนำสถานการณ์เหล่านั้นไปทำเป็น Acceptance Test แบบอัตโนมัติโดยตรง ซึ่งจะช่วยลดความสับสนได้
ในส่วนของขั้นตอนการดำเนินงาน ในช่วงสองสามสัปดาห์แรกควรให้ฝ่ายธุรกิจและนักพัฒนานั่งทำงานร่วมกันเพื่อฝึกเขียน "Given/When/Then" หากไม่กำหนดรูปแบบให้เป็นมาตรฐานตั้งแต่ตอนนี้ ความสัมพันธ์ระหว่างสถานการณ์กับโค้ดทดสอบจะพังลงในภายหลัง และส่งผลให้ต้นทุนการดูแลรักษาเพิ่มขึ้น จากนั้นจึงเข้าสู่ขั้นตอนการเชื่อมต่อสถานการณ์ที่เขียนเสร็จแล้วเข้ากับเครื่องมืออย่าง Cucumber เพื่อให้ทำงานเป็น Acceptance Test ที่รันได้จริง
สิ่งที่ควรระวังคือกรณีที่ทีมงานแยกกันทำระหว่างการกำหนดคำศัพท์ของ BDD กับกระบวนการสร้างข้อตกลงของ ATDD เพราะมักจะนำไปสู่สถานการณ์ที่มีเกณฑ์การยอมรับสำหรับฟังก์ชันเดียวกันแต่เขียนด้วยสำนวนที่ต่างกัน ทำให้ต้องเสียเวลามาบูรณาการในภายหลัง ดังนั้น ควรเริ่มจากการกำหนดอภิธานศัพท์และเทมเพลตสถานการณ์ให้เหลือเพียงชุดเดียว และจัดตั้งระบบที่ทั้งฝ่ายธุรกิจ QA และนักพัฒนาสามารถอ้างอิงเอกสารชุดเดียวกันได้ตั้งแต่ต้น เพื่อให้สามารถใช้งานทั้งสองวิธีควบคู่กันไปได้อย่างราบรื่น
ผู้เขียน・ผู้ตรวจสอบ
Yusuke Ishihara
เริ่มเขียนโปรแกรมตั้งแต่อายุ 13 ปี ด้วย MSX หลังจบการศึกษาจากมหาวิทยาลัย Musashi ได้ทำงานพัฒนาระบบขนาดใหญ่ รวมถึงระบบหลักของสายการบิน และโครงสร้าง Windows Server Hosting/VPS แห่งแรกของญี่ปุ่น ร่วมก่อตั้ง Site Engine Inc. ในปี 2008 ก่อตั้ง Unimon Inc. ในปี 2010 และ Enison Inc. ในปี 2025 นำทีมพัฒนาระบบธุรกิจ การประมวลผลภาษาธรรมชาติ และแพลตฟอร์ม ปัจจุบันมุ่งเน้นการพัฒนาผลิตภัณฑ์และการส่งเสริม AI/DX โดยใช้ generative AI และ Large Language Models (LLM)


