มุมมอง:
งั้นลองย้อนกลับไปถามว่า TDD กำลังพยายามช่วยพวกเราด้วยอะไร TDD พยายามช่วยเราพิจารณาว่ารหัสของเราถูกต้องหรือไม่ และถูกต้องฉันหมายถึง "รหัสนี้ตรงตามข้อกำหนดทางธุรกิจหรือไม่" จุดขายคือเรารู้ว่าจะต้องมีการเปลี่ยนแปลงในอนาคตและเราต้องการตรวจสอบให้แน่ใจว่ารหัสของเรายังคงถูกต้องหลังจากที่เราทำการเปลี่ยนแปลงเหล่านั้น
ฉันนำมุมมองนั้นมาใช้เพราะฉันคิดว่ามันง่ายที่จะหลงทางในรายละเอียดและมองไม่เห็นสิ่งที่เรากำลังพยายามจะทำ
หลักการ - SAP:
ในขณะที่ฉันไม่ใช่ผู้เชี่ยวชาญใน TDD ฉันคิดว่าคุณขาดส่วนหนึ่งของ Single Assertion Principle (SAP) ที่พยายามจะสอน SAP สามารถปรับปรุงใหม่เป็น "ทดสอบครั้งละหนึ่งสิ่ง" แต่ TOTAT ไม่ได้ใช้ภาษาอย่างง่ายเช่นเดียวกับ SAP
การทดสอบสิ่งหนึ่งครั้งหมายความว่าคุณมุ่งเน้นไปที่กรณีหนึ่ง เส้นทางเดียว; เงื่อนไขขอบเขตหนึ่ง กรณีข้อผิดพลาดหนึ่ง หนึ่งสิ่งต่อการทดสอบ และแนวคิดการขับขี่ที่อยู่เบื้องหลังคือคุณต้องรู้ว่าเกิดอะไรขึ้นเมื่อกรณีทดสอบล้มเหลวดังนั้นคุณสามารถแก้ไขปัญหาได้เร็วขึ้น หากคุณทดสอบหลายเงื่อนไข (เช่นมากกว่าหนึ่งอย่าง) ในการทดสอบและการทดสอบล้มเหลวคุณจะต้องทำงานหนักมากขึ้น ก่อนอื่นคุณต้องระบุว่ากรณีใดบ้างในหลายกรณีที่ล้มเหลวแล้วจึงหาสาเหตุของปัญหานั้น
หากคุณทดสอบสิ่งหนึ่งครั้งขอบเขตการค้นหาของคุณจะเล็กลงมากและข้อบกพร่องจะถูกระบุได้เร็วขึ้น โปรดทราบว่า "การทดสอบทีละรายการ" ไม่จำเป็นต้องกีดกันคุณจากการดูผลลัพธ์กระบวนการมากกว่าหนึ่งครั้ง ตัวอย่างเช่นเมื่อทำการทดสอบ "เส้นทางที่รู้จักดี" ฉันอาจคาดหวังว่าจะเห็นค่าเฉพาะผลลัพธ์ที่เกิดขึ้นfoo
รวมถึงค่าอื่นในbar
และฉันอาจยืนยันว่าfoo != bar
เป็นส่วนหนึ่งของการทดสอบของฉัน กุญแจสำคัญคือการจัดกลุ่มการตรวจสอบผลลัพธ์ทางตรรกะตามกรณีและปัญหาที่กำลังทดสอบ
หลักการ - PMP:
ในทำนองเดียวกันฉันคิดว่าคุณขาดอะไรเล็กน้อยเกี่ยวกับหลักการของวิธีการส่วนตัว (PMP) ที่จะสอนเรา PMP กระตุ้นให้เราปฏิบัติต่อระบบเหมือนกล่องดำ สำหรับอินพุตที่กำหนดคุณควรได้รับเอาต์พุตที่กำหนด คุณไม่สนใจว่ากล่องดำสร้างผลลัพธ์อย่างไร คุณสนใจว่าเอาต์พุตของคุณสอดคล้องกับอินพุตของคุณ
PMP เป็นมุมมองที่ดีมากสำหรับการตรวจสอบแง่มุม API ของโค้ดของคุณ นอกจากนี้ยังสามารถช่วยให้คุณกำหนดขอบเขตสิ่งที่คุณต้องทดสอบ ระบุจุดอินเทอร์เฟซของคุณและตรวจสอบว่าพวกเขาปฏิบัติตามข้อกำหนดของสัญญาของพวกเขาหรือไม่ คุณไม่จำเป็นต้องสนใจว่าวิธีการที่อยู่เบื้องหลังอินเทอร์เฟซ (aka ส่วนตัว) วิธีการทำงานของพวกเขา คุณเพียงแค่ต้องยืนยันว่าพวกเขาทำในสิ่งที่ควรทำ
ใช้ TDD ( สำหรับคุณ )
ดังนั้นสถานการณ์ของคุณจะมีรอยย่นเล็กน้อยเกินกว่าแอปพลิเคชันทั่วไป วิธีการของแอปของคุณมีสถานะดังนั้นการส่งออกของพวกเขาจะเกิดขึ้นไม่เพียง แต่การป้อนข้อมูล แต่ยังมีสิ่งที่ทำมาก่อน ฉันแน่ใจว่าฉันควร<insert some lecture>
ที่นี่เกี่ยวกับสถานะที่น่ากลัวและ blah blah blah แต่นั่นไม่ได้ช่วยแก้ปัญหาของคุณ
ฉันจะสมมติว่าคุณมีตารางไดอะแกรมสถานะที่แสดงสถานะต่าง ๆ ที่อาจเกิดขึ้นและสิ่งที่ต้องทำเพื่อเริ่มทรานซิชัน ถ้าคุณทำไม่ได้คุณจะต้องใช้มันเพราะมันจะช่วยแสดงความต้องการทางธุรกิจสำหรับระบบนี้
การทดสอบ:ก่อนอื่นคุณจะต้องจบด้วยชุดการทดสอบที่เปลี่ยนแปลงสถานะ เป็นการดีที่คุณจะมีการทดสอบที่ออกกำลังกายการเปลี่ยนแปลงสถานะเต็มรูปแบบที่อาจเกิดขึ้น แต่ฉันสามารถดูสถานการณ์บางอย่างที่คุณอาจไม่จำเป็นต้องไปที่เต็มรูปแบบ
ถัดไปคุณต้องสร้างการทดสอบเพื่อตรวจสอบการประมวลผลข้อมูล การทดสอบสถานะเหล่านั้นบางส่วนจะถูกนำมาใช้ซ้ำเมื่อคุณสร้างการทดสอบการประมวลผลข้อมูล ตัวอย่างเช่นสมมติว่าคุณมีวิธีการFoo()
ที่มีผลลัพธ์ที่แตกต่างกันตามสถานะInit
และ State1
คุณจะต้องใช้ChangeFooToState1
การทดสอบของคุณเป็นขั้นตอนการตั้งค่าเพื่อทดสอบผลลัพธ์เมื่อ " Foo()
อยู่ในState1
"
มีความหมายบางอย่างที่อยู่เบื้องหลังวิธีการที่ฉันต้องการพูดถึง สปอยเลอร์นี่คือที่ที่ฉันจะทำให้โกรธนักปราชญ์
ก่อนอื่นคุณต้องยอมรับว่าคุณใช้บางสิ่งบางอย่างเป็นการทดสอบในสถานการณ์หนึ่งและการตั้งค่าในสถานการณ์อื่น ในแง่หนึ่งดูเหมือนว่านี่เป็นการละเมิดโดยตรงของ SAP แต่ถ้าคุณใช้เหตุผลเชิงตรรกะChangeFooToState1
ว่ามีจุดประสงค์สองประการคุณก็ยังคงพบกับจิตวิญญาณของสิ่งที่ SAP สอนเรา เมื่อคุณต้องการให้แน่ใจว่าFoo()
สถานะการเปลี่ยนแปลงจากนั้นคุณใช้ChangeFooToState1
เป็นแบบทดสอบ และเมื่อต้องการตรวจสอบFoo()
ผลลัพธ์ของState1
" เมื่ออยู่ใน" คุณจะใช้ChangeFooToState1
เป็นค่าติดตั้ง
รายการที่สองคือจากมุมมองที่ใช้งานได้จริงคุณจะไม่ต้องการทดสอบหน่วยการสุ่มทั้งหมดสำหรับระบบของคุณ คุณควรรันการทดสอบการเปลี่ยนสถานะทั้งหมดก่อนที่จะทำการทดสอบการตรวจสอบความถูกต้องของเอาต์พุต SAP เป็นแนวทางที่อยู่เบื้องหลังการสั่งซื้อ หากต้องการระบุสิ่งที่ชัดเจน - คุณไม่สามารถใช้บางอย่างเป็นการตั้งค่าหากการทดสอบล้มเหลว
วางไว้ด้วยกัน:
ใช้แผนภาพสถานะของคุณคุณจะสร้างการทดสอบเพื่อให้ครอบคลุมช่วงการเปลี่ยนภาพ อีกครั้งโดยใช้ไดอะแกรมของคุณคุณจะสร้างการทดสอบเพื่อครอบคลุมกรณีประมวลผลข้อมูลอินพุต / เอาท์พุตทั้งหมดขับเคลื่อนโดยรัฐ
ถ้าคุณทำตามวิธีการนั้นการbloated, complicated, long, and difficult to write
ทดสอบควรจะง่ายขึ้นเล็กน้อยในการจัดการ โดยทั่วไปแล้วควรจบลงให้เล็กลงและกระชับขึ้น (เช่นซับซ้อนน้อยกว่า) คุณควรสังเกตว่าการทดสอบนั้นแยกกันหรือแยกส่วนมากขึ้น
ตอนนี้ฉันไม่ได้บอกว่ากระบวนการนี้จะปราศจากความเจ็บปวดอย่างสมบูรณ์เพราะการเขียนแบบทดสอบที่ดีนั้นต้องใช้ความพยายามบ้าง และบางคนก็ยังคงเป็นเรื่องยากเพราะคุณกำลังทำการแมปพารามิเตอร์ที่สอง (สถานะ) กับกรณีของคุณค่อนข้างน้อย และเป็นเรื่องที่ชัดเจนว่าทำไมระบบไร้สัญชาตินั้นง่ายกว่าในการสร้างการทดสอบ แต่ถ้าคุณปรับวิธีนี้สำหรับแอปพลิเคชันของคุณคุณจะพบว่าคุณสามารถพิสูจน์ได้ว่าแอปพลิเคชันของคุณทำงานได้อย่างถูกต้อง