การเขียนชุดทดสอบอัตโนมัติ (Writing Automated Tests)
ในเรียงความปี 1972 หัวข้อ “The Humble Programmer” เอ็ดสเคอร์ ดับเบิลยู. ไดก์สตรา (Edsger W. Dijkstra) เคยกล่าวไว้ว่า “การทดสอบโปรแกรมสามารถเป็นวิธีการที่มีประสิทธิภาพอย่างยิ่งในการแสดงให้เห็นถึงการมีอยู่ของบั๊ก (bugs) แต่ทว่ามันไม่มีทางเพียงพอที่จะแสดงให้เห็นถึงการไม่มีอยู่ของมันได้เลย” ถึงกระนั้น นั่นก็ไม่ได้หมายความว่าเราไม่ควรพยายามทดสอบระบบให้มากที่สุดเท่าที่เราจะสามารถทำได้!
ความถูกต้อง (correctness) ในโปรแกรมของเราคือขอบเขตระดับที่โค้ดสามารถประมวลผลคำสั่งตอบสนองความตั้งใจของเราได้อย่างสมบูรณ์ ภาษา Rust ได้รับการออกแบบขึ้นโดยให้ความใส่ใจในระดับที่สูงมากเกี่ยวกับเรื่องความถูกต้องของโปรแกรม แต่ประเด็นคือความถูกต้องมีความซับซ้อนและไม่ง่ายที่จะพิสูจน์ได้หมด ระบบตรวจสอบประเภทข้อมูล (type system) ของ Rust ช่วยแบ่งเบาภาระในส่วนนี้ไปได้อย่างมหาศาล ทว่าระบบประเภทข้อมูลก็ไม่ได้มีความสามารถตรวจจับข้อบกพร่องได้ครอบคลุมทั้งหมด ด้วยเหตุนี้ ภาษา Rust จึงได้บรรจุระบบช่วยเหลือสำหรับการเขียนชุดทดสอบซอฟต์แวร์แบบอัตโนมัติเข้ามาให้ด้วย
สมมติว่าเราเขียนฟังก์ชันหนึ่งชื่อว่า add_two ซึ่งมีพฤติกรรมบวกค่าเพิ่มไปอีก 2 จากตัวเลขใด ๆ ก็ตามที่ส่งเข้ามา ซิกเนเจอร์ของฟังก์ชันนี้จะรับพารามิเตอร์นำเข้าเป็นเลขจำนวนเต็มและส่งค่ากลับคืนมาเป็นจำนวนเต็ม เมื่อเราเริ่มเขียนคำสั่งและคอมไพล์ฟังก์ชันนั้น Rust จะช่วยตรวจสอบประเภทข้อมูล (type checking) และตรวจสอบสิทธิ์การยืมใช้งาน (borrow checking) ทั้งหมดตามที่เราได้เรียนรู้กันมา เพื่อช่วยรับประกันว่าเราไม่ได้เผลอส่งข้อความ String หรือส่งข้อมูลอ้างอิงที่ไม่ถูกต้องเข้ามาในฟังก์ชันนี้ ทว่า Rust ไม่สามารถ เข้าไปช่วยตรวจสอบได้ว่าฟังก์ชันนี้จะทำงานได้ตรงตามเป้าหมายวัตถุประสงค์ของเราเป๊ะ ๆ (ซึ่งก็คือการนำพารามิเตอร์มาบวก 2 ไม่ใช่บวก 10 หรือลบ 50!) และนี่คือจุดที่ชุดทดสอบ (tests) เข้ามามีบทบาท
เราสามารถเขียนทดสอบเพื่อตรวจเช็คยืนยัน (assert) ตัวอย่างเช่น เมื่อเราป้อนค่า 3 เข้าไปในฟังก์ชัน add_two ผลลัพธ์ส่งคืนที่ควรได้จะต้องเป็น 5 เราจะสามารถสั่งรันชุดทดสอบเหล่านี้ได้ทุกครั้งที่มีการปรับเปลี่ยนแก้ไขโค้ด เพื่อให้มั่นใจได้เต็มเปี่ยมว่าพฤติกรรมการทำงานเดิมที่ถูกต้องอยู่ก่อนแล้วจะไม่มีจุดใดเปลี่ยนแปลงหรือทำงานผิดเพี้ยนไป
การทดสอบคือทักษะความสามารถที่มีความซับซ้อน: แม้ว่าเราจะไม่สามารถบรรจุอธิบายรายละเอียดทั้งหมดเกี่ยวกับแนวทางการเขียนชุดทดสอบที่ดีให้อ่านจบครบถ้วนได้ในบทเดียว แต่ในบทนี้เราจะเน้นอภิปรายถึงกลไกการทำงานพื้นฐานของระบบจัดทำชุดทดสอบของ Rust เราจะพูดคุยเกี่ยวกับสัญลักษณ์กำกับ (annotations) และมาโคร (macros) ต่าง ๆ ที่มีเตรียมไว้ให้ใช้งานสำหรับสร้างชุดทดสอบ พฤติกรรมการทำงานเริ่มต้นรวมถึงอ็อพชันต่าง ๆ ในการสั่งรันชุดทดสอบ และแนวทางการจัดหมวดหมู่ประเภทชุดทดสอบออกเป็น ชุดทดสอบระดับย่อย (unit tests) และ ชุดทดสอบระดับรวมระบบ (integration tests)