Test Talk

น
llun
Published in
1 min readMar 1, 2017

รู้สึกชีวิตกลับมาถึงวงจรที่คุยเรื่อง Test, Programming language, Code Quality อีกครั้งหลังจากห่างหายไปนานทั้งในที่ทำงานและ Social Network เลยรวบรวมที่คิดไว้หน่อยดีกว่า

เริ่มจากเมื่อวาน (หรือวันนี้ ไม่แน่ใจ) เพื่อนทักว่า Project ที่เริ่มทำเนี๊ยะ มันไม่ควรจะเริ่มจาก Unit Test นะแต่เริ่มจาก Integration Test เพื่อให้เห็น Behaviour โดยรวมเลยมากกว่า อีกอย่างเขียนไม่ต้องเยอะด้วย แล้วก็เลยตอบกลับแบบไม่เห็นด้วยไปว่า Integration Test ดีแต่ปัญหาของ Integration เริ่มต้นคือ Behaviour ของระบบมันไม่แน่นอน สิ่งที่ทำรวมๆ สุดท้ายแล้วอาจจะไม่ได้ Validate อะไรเลยแถม Regression ก็ไม่ได้ (เพราะระบบยังใหม่อยู่ มีแต่ feature ใหม่อย่างเดียว) กลายเป็นว่าจะเปลืองแรงมากกว่า Unit Test ซะอีก กลับกัน Unit Test อาจจะเขียนถี่กว่า เขียนเยอะกว่า แต่การแก้จะไม่ค่อยมีในระบบใหม่ๆ แต่เป็นโยนทิ้งทั้งชิ้นเลยมากกว่า ส่วนตัวแล้วจะรู้สึกว่า ภาพรวมของระบบจะไม่ปนกับสิ่งที่มีอยู่และเปลี่ยนได้เร็วกว่า

ถัดไปจากนี้ไปก่อนหน้าอีกซักพักสิ่งที่โดนเพื่อนกระตุ้นให้ทำบ่อยๆ คือ FlowType และเพื่อนพยายามโชว์ให้ดูว่า FlowType ยืม Functional มายังไงแล้วพอมาใช้กับ Redux แล้วมันดียังไง

สิ่งที่เห็นได้ชัดสุดหลังจากเพื่อนโชว์ FlowType แล้วมาเติม Jigsaw ที่ปกติทำ Unit Test แล้วรู้สึกหงุดหงิดมาตลอด มาเต็มตอนนี้คือเวลาเขียน Unit Test คลุมชั้น Model (หรือ Reducer) เวลาเพิ่ม/ลด Property ต่างๆจะเป็นปัญหามาก เพราะรูปร่างหน้าตาเปลี่ยนทีโดนทุกชั้น เอาแค่ Unit Test ชั้น model เองก็ทำให้คลุมการเปลี่ยนแปลงของ property ไม่ไหว พอมี property เพิ่มทีส่วนใหญ่ก็จะคลุมแค่สิ่งที่เพิ่มนั่นแหละ

FlowType เข้ามาแก้คือแทนที่จะเอา Unit Test มาเขียนอธิบายว่า Model หน้าตาเป็นยังไง Posible Value มีอะไรบ้าง ก็ประกาศไปเลย Model นี้จะมีหน้าตาอย่างนี้นะ มี Type ตามนี้และ Posible Value มีตามนี้จบ แล้วเช็คเอาทั้งระบบมี Type อะไรบ้าง mutate property value แล้วไม่ตรงกับที่ประกาศป่าว ความง่าย และความเยอะต่างกันมาก แต่ Unit Test ไร้ประโยชน์ที่เขียนคือมาเพื่อเช็ค Identity ก็หายไปด้วย เพิ่มความเร็วในการ run test โดยรวมอีกต่างหาก

อีกเรื่องที่ผ่านมาซักพักนานๆ แล้วคือ ความเร็วในการ run test โดยรวม

ส่วนตัวแล้ว Integration, End to End เป็นอะไรที่รับได้ในความช้า และมันช้าโดยมีเหตุผลของมันเพราะว่าต้องทดสอบกับ Environment จริง จะทำให้มันเร็วยังไงสุดท้ายก็มี limit ตามกำลังเงินที่มี (คือเร็วขึ้นได้ด้วยการทำให้ Environment มัน Parallel) หรือตามความซับซ้อนของระบบ แต่สิ่งที่ยังไงก็รับไม่ได้คือ unit test ช้า

ข้อจำกัดสูงสุดที่ตัวเองกำหนดไว้ตอนนี้คือ unit test รวมทั้งหมดต้องใช้เวลาในการทำงานไม่เกิน 10 นาที ตอนนี้ project ที่ดูอยู่รวมๆ กันแล้วก็อยู่ประมาณ 3–4 นาที เรียกว่ารับได้ สาเหตุที่ unit test ต้องเร็วเพราะว่าเป็นอะไรที่จะถูกเรียกใช้บ่อยสุด ทั้งใน CI และ Developer machine เองถ้าส่วนนี้ช้าเมื่อไหร่ จำนวน test ที่จะถูกเขียนรับรองได้ว่าลดลงเรื่อยๆ จนทุกคนหยุดเขียนแน่ๆ

วิธีการที่ตอนนี้ใช้คือทุกอย่างต้อง parallels ได้ ตอนนี้ framework ที่ใช้คือ ava.js ก็ทำได้ดี เสียอย่างเดียวไม่ค่อยชอบ syntax มากนัก ที่เสียดายสุดหลังจากย้ายจาก jasmine มา ava คือ matcher ของ jasmine นั้นเทพมาก แต่เพื่อความเร็วยอม ตอนนี้ก็หวังว่าจะมีคนทำ assertion library ที่ทำ matcher ได้แบบ jasmine แล้ว opensource ให้ใช้

ข้อจำกัดของ unit test อีกอย่างที่จะทำให้คนเลิกเขียนคือ ความยากในการเขียน test แต่ประเด็นนี้จริงๆ แล้วมันไม่ใช่ความผิดของ unit test เสียทีเดียว ส่วนใหญ่จะเป็นเพราะ ความซับซ้อนของระบบมากกว่า

ส่วนตัวแล้วถ้า unit test เริ่มเขียนยากเมื่อไหร่ก็ถึงเวลาแล้วที่ต้อง refactor code ที่ทำอยู่ให้เขียนง่ายขึ้น แล้วทุกอย่างก็จะดีขึ้นเอง

รวมๆ แล้วช่วงนี้ก็มีประมาณสามประเด็นที่ถกกันรอบๆ ตัว ไว้เริ่มทำ Integration Test/End-to-End Test จริงจังเมื่อไหร่คงมีประเด็นมากกว่านี้แน่ แล้วไว้จะเขียนเพิ่มอีกรอบ

--

--

น
llun
Editor for

Coder, mostly in Javascript/Typescript. Posting in https://llun.me