อาทิตย์ที่ผ่านมาเริ่ม Push TDD ให้ทีม Dev ทั้งทีมก็มีเสียงตอบกลับมาทันที ซึ่งเป็นสิ่งที่อยากได้และจะได้เอาไปปรับปรุง เสียงตอบอันนึงที่กลับมาถูกบล๊อกโดย @teerapapc ผ่านหัวข้อนี้ “My experience with unit testing in software development” สรุปสั้นๆ คืออยากให้คนอื่นเป็นคนเขียน Test ในตอนท้ายของบทความ
จริงๆ เรื่องเขียน UnitTest สำหรับ Dev หลายคนที่พึ่งจบออกจากมหาวิทยาลัยและเขียนโปรแกรมเล่นตามสิ่งที่สนใจ มักเป็นสิ่งที่อยู่ห่างไกลกันเหลือเกิน แม้แต่ตัวเองตอนจบใหม่ๆ และทำงานได้สองสามปีแรก ก็ไม่รู้ว่าจะเขียน Test ยังไงเพราะขั้นตอนการทำงานเริ่มจาก
- ได้ Requirement มาจาก Manager
- จากนั้นก็เริ่มเขียน Module ต่างๆ ตามที่คิดไว้
- ลองรันดูว่ามันทำงานถูกต้องตามที่ Manager ให้มามั้ย
- ปิดเคส
ด้านบนคือช่วงก่อนที่จะมี QA ช่วงที่มี QA เข้ามาก็จะมีขั้นตอนเพิ่มก่อนปิดเคสคือ ส่งให้ QA เล่น จากนั้นงานก็จะเด้งเป็นปิงปองซักพัก ก่อนจะปิดได้ (บางงาน ปิงปองระหว่าง QA – Dev หลายคนด้วย)
ถ้าเป็นระบบที่ทำใหม่หมดขั้นตอนก็เปลี่ยนไปนิดหน่อยคือ
- ได้ Requirement มา
- หาคำนามใน Requirement แปลงออกมาเป็น Model ต่างๆ
- เขียนตาม Model นั้นพร้อมกับสร้าง Module ตาม Behavior ของแต่ละคนแยกกันไป
- ส่งไปให้ QA เล่น
- เล่นปิงปองระหว่าง QA กับ Dev อีกครั้ง
- ปิดเคส
สิ่งที่หายไปจากขั้นตอนด้านบนทั้งสองอันคือการกำหนดการกระทำต่างๆ ของระบบที่ได้จาก Requirement เช่นระบบบัญชี ก็จะมีขั้นตอนการทำงานต่างๆ ตั้งแต่การนำตัวเลขมาป้อนเข้าระบบ จากนั้นตรวจสอบว่าสิ่งที่ใส่เข้ามาอยู่ในรูปแบบที่ถูกต้องมั้ย ถึงเอาไปประมวลผลบางอย่างเพื่อให้ได้ผลลัพธ์ออกมาตามที่กำหนด
จากขั้นตอนด้านบนส่วนใหญ่จะถูก Dev ลัดขั้นตอนไปเขียนโปรแกรมตามพฤติกรรมเลย ไม่สนใจการกำหนด input/output ขึ้นมาก่อน เพราะคิดว่า function หรือ class ที่เราเขียนตัวฟังก์ชั่นคือการ define input และ Return ก็คือ output ของระบบอยู่แล้ว พองานมันซับซ้อนมากขึ้น เราก็พยายามแยกงานบางส่วนออกไปอีก function อีก class โดยที่ไม่สนใจ define input/output และหน้าที่ของแต่ละชั้นให้ชัดเจนอีก สุดท้ายกลายเป็นว่า การทำงานมันกระจายข้ามกันหลายชั้นมาก จะทดสอบชั้นย่อยๆ ก็ทำได้ยาก เลยต้องไปทำจากด้านนอก ทดลองรันทุกชั้น เพื่อให้ได้ผลลัพธ์ออกมาจาก output ที่หลากหลาย ทั้งๆ ที่ถ้าทดสอบแต่ละชั้นแล้ว input ที่มีจะน้อยกว่าทุกชั้นรวมกันมาก
เอาหละ ในเมื่อลัดขั้นตอนกันหมดแล้ว ไม่มีการกำหนด Spec กันมาก่อน การจะมาแก้สิ่งที่เคยทำไปแล้วจะให้คนนอกมาเขียนโดย Define input/output ของคนอื่นก็คงทำไม่ได้ เพราะถึงทำได้คนนอกก็ไม่รู้ขอบเขตของแต่ละชั้นที่ Dev เป็นคนทำอยู่ดี คนที่ควรจะรู้ว่าแต่ละชั้นทำงานอย่างไรมากสุด ก็ควรจะเป็นคนที่สร้างสิ่งเหล่านั้นขึ้นมา ไม่งั้น Dev ก็ไม่ควรจะสร้าง function ขึ้นมาได้ทั้งๆ ที่ไม่รู้ input และสิ่งที่ตัวเองต้อง return ออกมา แต่ปรากฏว่าหลายๆ ครั้ง Dev ลืมว่าตัวเองสร้างอะไรไป ทำงานยังไงเพราะเวลามันผ่านไปนานพอสมควร ก็ต้องค่อยๆ ไล่สิ่งที่ตนเองเขียนขึ้นมา บางครั้งก็บอกไม่ได้ว่าตัวเองทำอะไรไปในตอนนั้น ทำไปทำไม แถมไม่มีอะไรบอกอีกว่า input อะไรส่งมาจากชั้นก่อนหน้า และ return อะไรออกไป สุดท้ายก็ปล่อยมันไปและก็สมมุติว่ามันทำงานถูกต้องต่อไป
บ่นมาเยอะเกินครึ่งหน้าจริงๆ อยากจะเขียนแค่ว่าการจะเขียน test ให้สนุก ง่ายไม่ซ้ำซ้อนกับการเขียน code จริงๆ แล้วไม่ยากเลยเพียงแต่ต้องกำหนด input/output ของสิ่งที่เราจะ test เท่านั้นเอง ระบบใดๆ ส่วนย่อยสุดประกอบด้วยสามอย่าง คือ input/process/output ส่วนย่อยบางส่วนอาจจะไม่มี input บางตัว input อาจจะลึกลับหน่อยเป็นตัวแปรกลางที่หลายคนเรียกว่า state แต่ถ้าเรากำหนด input/output ได้ครบแล้ว สิ่งที่ Dev เขียนก็ไม่ควรจะมีอะไรลึกลับที่ทำงานแล้วได้สิ่งที่เราไม่คาดคิดอีก ถ้าระบบใดมี output ที่เราไม่เคยเจอ แปลว่าสิ่งที่เราทดลองต้องมี input บางอย่างที่ขาดหายไป
วิธีการหา input พวกนี้ส่วนใหญ่จะได้มาจากตอนเรียนในมหาวิทยาลัยนั่นแหละ ตั้งแต่การเขียน State diagram, Sequence diagram, … diagram ทั้งหลาย การเขียน diagram พวกนั้นก็คือการหาหน้าที่ และ input/output ของระบบที่เราจะทำนั่นแหละ เราใช้อันไหนแล้วเห็นภาพมากกว่ากันก็เลือกอันนั้น สำหรับผม diagram ที่เขียนแล้วเห็นภาพสุดก็คงเป็น Sequence เพราะมันเห็นชั้นต่างๆ และสามารถคิดและกำหนดหน้าที่แต่ละชั้นได้ บางคนอาจจะเป็น State เพราะจะได้กำหนด input ที่ถูกซ่อนอยู่ให้หมด จริงๆ อีกวิธีที่นิยมในปัจจุบันก็คือการเขียน test หรือกำหนด behavior ขึ้นมาเป็นภาษาโปรแกรม ก็เป็นการ define input/output อย่างนึง ก็แล้วแต่คนชอบ แต่ยังไงก็ต้องมีการ define พวกนี้มาก่อนที่จะเขียนโปรแกรมขึ้นมาให้ทำงาน การกำหนดพวกนี้ จะเป็นคนที่เขียน code เองเป็นคนทำหรือให้คนอื่นเป็นคนทำ แล้ว Dev ก็เป็นแค่ labor เขียน code ตามคำสั่งก็ได้แล้วแต่ความถนัดของแต่ละคน แต่ถ้า Dev เป็นคนที่ต้องคิดถึงหน้าที่และขั้นตอนการทำงาน Dev เป็นคนเขียนเองนั่นแหละจะดีที่สุด จะได้ตรงใจ Dev เองไม่ต้องเล่นปิงปองระหว่าง Manager/Dev อีก
Pingback: Backup My Bookmark Table | MzSoft