เขียนโค๊ดมาเป็นสิบ ๆ ปี วันนี้มีคนมาบอกว่า “ยูต้องเขียน Unit Test นะ”

เกริ่นนิดคือ Unit Testing เนี่ยมันเริ่มแพร่หลายประมาณช่วงต้น 2000 ครับ ดังนั้นถ้าเป็นโปรแกรมที่เขียนมาเป็นสิบ ๆ ปี จะไปถามหา Unit Test แล้วดันมีขึ้นมาเนี่ย เรียกว่าปาฎิหารย์เลยก็ยังได้

Unit Testing อย่างที่เคยพูดถึงหลาย ๆ ครั้ง มันคือการทดสอบโค๊ดที่ระดับหน่วยย่อย ก็คือที่ระดับฟังก์ชันและระดับคลาส โปรแกรมเก่า ๆ มักจะไม่มีเพราะมักจะเป็นการทดสอบด้วยมือ และการใช้มือเรียกใช้ฟังก์มันก็ออกจะลำบากนิดนึง (ทำได้แต่อัตราการปนเปื้อนสูง) และทั้งตัวนักพัฒนาและผู้บริหารเองจะไม่ค่อยเห็นความสำคัญเท่าไหร่ ก็เพราะมันเป็นโปรแกรมที่เอาไปคิดเงินลูกค้าไม่ได้นั่นเอง แต่ในระยะยาวมันสำคัญมาก ๆ เพราะมันเป็นการแสดงความชัดเจนของโปรแกรม (ว่าหน่วยโค๊ดนั้น ๆ ทำอะไร ผลลัพท์ที่ได้ควรเป็นอย่างไร และอินพุตชุดไหนที่รองรับแน่นอน) และความน่าเชื่อถือของโปรแกรม (โปรแกรมที่ทดสอบบ่อยจะมีอัตราการเกิดปัญหาต่ำกว่า)

ทีนี้จะเขียน Unit Test ได้ดีได้นั้น ส่วนสำคัญอย่างหนึ่งคือตัวหน่วยโค๊ดเอง ก็คือตัวโปรแกรมจะต้องออกแบบมาให้ทดสอบได้ง่าย มีการแบ่งสัดส่วนที่ชัดเจน แต่ละโปรซีเยอร์จะทำงานแค่อย่างเดียว โปรแกรมลักษณะนี้จะออกแบบ Unit Test ได้ง่ายและมีประสิทธิภาพ ในทางกลับกันถ้าเป็นโค๊ดที่เขียนมาไม่ดีนั้น การทดสอบจะทำได้ยากมาก ๆ

นึกสภาพ … ฟังก์ชันเดียว แต่คืนค่าผลลัทพ์ออกมาสองร้อยกว่าชิ้นโดยที่ไม่มีความเกี่ยวข้องกันเลยดูนะครับ … การเขียน Unit Test กับฟังก์ชันแบบนี้นี่ฝันร้ายเลยนะ (ฟังก์ชันแบบนี้มีจริง ๆ ครับ)

ผมเคยเล่าให้ฟังในส่วนของ Legacy Code ว่า Legacy Code ก็คือโค๊ดที่ไม่มี Unit Test กำกับ (เป็นโค๊ดที่ไม่เป็นที่ต้องการ) และเคยเขียนไว้อีกว่า การจะสร้าง Unit Test ได้นั้นจำเป็นจะต้องมีการ Refactor โปรแกรมด้วย ไม่เช่นนั้นต่อให้เขียนออกมาได้ Unit Test ก็ไม่ครอบคลุมครับ นึกสภาพฟังก์ชันข้างบนไว้แล้วคิดเล่น ๆ ว่าแล้วจะทดสอบยังไงดูก็ได้ครับ

ทีนี้ปัญหาของ Legacy Code อีกอย่างคือ สมมติว่าถ้าเราประกาศว่า “เอ้า มาทำ Unit Test กันเถอะ” ปฎิกิริยาแรกที่จะเจอคือ “ภาระฉันเพิ่ม ทำไมต้องทำด้วย” โดยเฉพาะอย่างยิ่งถ้าเป็นคนที่ไม่ได้เขียนโค๊ดใหม่ แต่เป็นการแก้ไฟล์เก่า บางทีเราเพิ่มแค่บรรทัดเดียว แต่ต้องเขียน Unit Test ให้ครอบคลุมกับทั้งโปรซีเยอร์ … คือ ร้องโอ้พระสงฆ์กันเลยล่ะครับ

คือต้องเข้าใจก่อนว่า คนสมัยก่อน เขาแก้โค๊ด เขาก็จะทดสอบกับเฉพาะปัญหาที่เขาแก้ เขาไม่เสียเวลามาดูปัญหาที่เขาไม่ได้ถูกสั่งให้แก้ไงครับ

แต่ในระยะยาว ไอ้เทสต์ที่เขาเขียนมันจะมาช่วยยืนยันว่า โค๊ดที่เราแก้ไปมันไม่ไปกระทบส่วนที่เราไม่ได้แก้น่ะครับ การมี Unit Test มันถึงเป็นเรื่องดีไง

คือผมคิดว่า Unit Test มันจะเป็นประโยชน์ในระยะยาว แต่ถ้าเราบอกว่าให้คนมาเขียน Unit Test แบบ “เฮ้ย ถ้ายูแก้ไฟล์นี้ ยูเขียน Unit Test ให้ด้วยนะ” แบบนี้มันก็ดูจะไม่เป็นธรรมกับคนเขียนโค๊ดเท่าไหร่ ผมคิดว่าทางที่ดีควรจะทำเป็นโครงการ กำหนดทิศทางและขอบเชตให้แน่นอน และค่อย ๆ เพิ่ม Unit Test เข้าไป พร้อมกับ Refactor โค๊ดให้อยู่ในสภาพที่ทดสอบได้ดีด้วย ไม่ใช่แค่ว่าเราจะยัด Unit Test เข้าไปในโปรแกรมเดิมแล้วมันจะใช้งานได้ครับ …

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

This site uses Akismet to reduce spam. Learn how your comment data is processed.