Test-driven development

posted on 06 Feb 2008 21:05 by wonam in softdev

จริง ๆ ผมก็สอนเรื่องพวกนี้ในวิชา Software Testing แต่ก็แย่มากที่ไม่ค่อยได้ทำเอง (เป็นความเศร้าอย่างหนึ่ง)

แม้ว่าตอนนี้เขาจะค่อย ๆ ขยับไป Behavior-driven development (ดูวิกิพีเดีย) (ดูบล็อก PunNeng) กันแล้วก็ตาม ผมคงค่อย ๆ ตามเขาไปละกัน

วันก่อนเขียน Rails app มีส่วนหนึ่งที่ทำเกี่ยวกับการแสดงตารางสอนที่ค่อนข้างยุ่งยาก ก็เลยได้โอกาสลองเล่นดู

พักหลังผมพยายามทำตามคำแนะนำ: skinny controllers, fat models (หรืออันนี้) (แม้ว่า poomk จะบอกว่านางแบบจะอ้วนไม่ได้ก็ตาม) ในระบบผมก็เลยมีโมเดลหลายอันที่ไม่ได้อ้างอิงกับตารางในฐานข้อมูล

ทีนี้ unit testing ใน Rails โดยปกติก็จะมีการโหลด/ติดต่อกับฐานข้อมูลที่ตั้งค่าในสภาพแวดล้อม test อยู่ แต่ผมเองไม่มีฐานข้อมูลตรงนี้

ไปกด ๆ อ่านดูก็เจอบล็อกของคุณ Jay Fields ที่เขียนเกี่ยวกับ unit testing บน rails ควรจะทดสอบเฉพาะ unit เท่านั้นไม่ควรเชื่อมโยงกับอย่างอื่น ส่วนอื่น ๆ ที่ต้องการให้ mock หรือ stub เอา

ทีนี้ ส่วนที่ผมต้องการ test ยังไม่ได้มีการขึ้นต่อกันขนาดนั้น เพียงแต่ว่า ไม่ต้องการติดต่อกับฐานข้อมูลตามที่กำหนดไว้ตามปกติ ก็เริ่มโดยการสร้าง unit_test_helper ตามที่คุณ Jay Fields เขียนไว้ แล้วก็ทำตามที่เคยสอนไว้ คือ เขียน unit test ก่อน แล้วค่อยไปเขียนโปรแกรม พอผ่าน ก็เพิ่ม test case แล้วก็แก้โปรแกรมเพิ่ม

สนุกมาก

แถมทำให้รู้ว่า บางทีการทำ metaprogramming เป็นก็น่าจะช่วยมาก

ในโปรแกรมผมมีส่วนสร้าง object Time บ่อยมาก ทีนี้ผมไม่รูว่าจะสร้างอย่างไร นอกจากสั่ง Time.local(2000,1,1,hour,min) ทีนี้ มันยุ่งมากจะเขียน method ก็ดูไม่ค่อยสวย

จริง ๆ ถ้าเราจัดการให้สั่ง t9_30 แปลงเป็นเวลา 9:30 หรือ t10_00 แปลงเป็นเวลา 10:00 ได้ก็คงดี (ตอนนี้ทำเป็นแล้ว --- แต่ทำเป็นเมื่อสาย) ถ้าแค่ตอบสนองแบบ dynamic อย่างเดียวก็จะเป็นประมาณนี้:

class MyTest
..def method_missing(meth, *args)
....m = meth.to_s
....if (res=/^t(\d+)_(\d+)/.match(m))         # ตรวจชื่อ method 
......Time.local(2000,1,1,res[1].to_i,res[2].to_i)    # สร้าง object
....end
..end
end  

(จุด ๆ ด้านหน้าสำหรับทำย่อหน้าให้สวย) เมท็อด method_missing จะเป็นเมท็อดทีถูกเรียกทำงานโดยอัตโนมัติ เมื่อ object ได้รับ message ที่ไม่ได้ระบุไว้ (เอาง่าย ๆ คือมีการเรียกเมท็อดที่ไม่รู้จัก) เมท็อดนี้จะทำให้เรามีโอกาส "จัดการ" สิ่งที่เราไม่ได้เตรียมไว้ได้ เช่น ในกรณีนี้คือมีการเรียกเมท็อด เช่น t9_30 โดยในโปรแกรมข้างบนผมแกะเลข 9 กับ 30 ออกมาจากชื่อเมท็อดแล้วก็เอามาสร้างเป็น object Time ตามต้องการ

[จริง ๆ เคยคิดแวบหนึ่งเหมือนกันว่าจะไปเพิ่มเมท็อด am กับ pm ในจำนวนเต็มกับจำนวนจริง จะได้เขียนเป็น 9.pm หรือ 10.30.am ได้ --- แต่อย่าดีกว่า เดี๋ยวจะมัวแต่เล่นไม่ได้เขียนโปรแกรมพอดี]

Comment

Comment:

Tweet

time นี่ใส่ hash เอาดีเปล่าครับ? แบบ
Time.local :hour => 10, :minute => 30
(แต่ว่าไปแล้ว Hash แบบใน Rails ผมก็ยังงงๆอยู่เลย ลอล.)

#2 By veer on 2008-02-06 22:59

นางแบบอึ๋มแบบนางแบบชุดชั้นใน ภาษาอังกฤษเรียกอะไรอะครับ?

เวลาทดสอบ controller เรา mock model ได้เปล่าครับ? ใน rails.

#1 By veer on 2008-02-06 22:51