Unit Test จากประสบการณ์อันน้อยนิด by

31
May
0

จากประสบการณ์อันน้อยนิดของผมในการใช้ unit test เข้ามาช่วยในการทำงานเป็นเวลาเกือบ 2 เดือน ทำให้รู้ว่า unit test มีประโยชน์ แน่นอน ในหลายๆ เรื่อง แต่ความมีประโยชน์ของมันก็ต้องแลกมาด้วยเวลาแน่นอน และจากการที่ได้ทำงานมาหลายๆ แบบ เช่น เขียนแต่ code อย่างเดียว, คนเดียวเขียนทั้งโค้ดเขียนทั้ง test, เขียนสองคนแยกันคนนึงเขียนโค้ด คนนึงเขียน test ก็ได้เจอข้อดีข้อเสียที่แตกต่างกัน เลยจะมาเล่าสู่กันฟัง ^^

เขียนแต่โค้ด only
เขียนโค้ดอย่างเดียว แน่นอนเขียนเพลินสบายใจ แต่อาจน้ำตาตก ยกโคลงทั้งแผงได้แน่ ถ้าคุณออกแบบโครงสร้างของโค้ดมาไม่ดีพอ อีกทั้งสิ่งที่ตามมาพร้อมๆ กับโค้ดเสมอ นั่นก็คือ บั๊ก ยิ่งโค้ดเยอะ บั๊กก็เยอะตาม ซึ่งต้องมาคอยปรับแก้ไขทุกครั้งหลังโค้ดเสร็จสิ้น แล้วใช่ว่าจะหาเจอง่ายๆ นะว่าโค้ดมันผิดตรงไหนเนี่ย ยิ่งถ้าคิด test case ยังไม่หมดครบทุกแบบด้วยนี่ ก็อาจจะได้เขียนแปะ เขียนปะ โค้ดไปเรื่อยๆ เพราะตัว core โค้ดอาจไม่ได้ครอบคลุม เมื่อทำไปเรื่อยๆ สุดท้าย ก็อาจจะเหมือนอย่างที่บอกไปตอนแรกครับ ยกแผงเลย ที่พูดมามีแต่ข้อเสีย ใช่ว่ามันจะไม่มีข้อดีนะครับ มันเร็วไงครับ ถ้าออกแบบโครงสร้างมาดีพอ ก็จะแก้บั๊กนิดๆ หน่อยๆ ก็เสร็จเรียบร้อยแล้ว ซึ่งจากประสบการณ์แล้ว จะเป็นแบบนี้ได้ยากมาก ถึงเป็นไปไม่ได้ T T

เขียนคนเดียวเบย ทั้งโค้ด ทั้ง test
รับตำแหน่งทั้งสองบทบาท งานหนักเลยครับ อย่างแรกต้องไปเขียน test ก่อน เพราะคุณการที่จะเขียน test ได้คุณต้องออกแบบโครงสร้างทั้งหมดให้เรียบร้อยก่อน ไมงั้นเขียนไม่ออกแน่ (เหมือนโดนบังคับ) จากนั้นต้องออกแบบว่า function นี้ทำไร input output เป็นอย่างไร
ถึงจะเขียน test ได้ เขียนเสร็จปุ๊บ แนะนำให้เขียน test ที่ละ function แล้วค่อยโค้ดให้เสร็จ แล้วไปต่อ function ถัดไป จะทำให้ไม่ต้องระลึกชาตินานมากกว่าจะนึกออกว่า function นี้มานทำไรบ้าง

ข้อดีก็คือ เขียน test ด้วยเนี่ยแน่นอน ลด bug ไปเยอะ เพราะมันเป็นการบังคับคุณให้ออกแบบโครงสร้างทั้งหมดก่อน มันจะช่วยให้คุณคิด test case ให้มากพอที่จะคิดออก แล้วใส่ลงไปใน test ซะ ตอนแรกคุณจะเบื่อกับ test มากเพราะคิดว่าเขียนไปช่วยอะไรไม่ได้มากเท่าไหร่ไม่คุ้มค่าเหนื่อยเลย ต้องลองครับเดี๋ยวรู้เอง เพราะถ้าคุณเขียนโค้ดอย่างเดียว test case ที่คุณนึกออกอยู่อาจเลื่อนหายไปบาง case ระหว่างเขียน และพอคุณเจอบั๊ก ก็ต้องมานั่งงมกับ test case ที่หายไปตัวนั้น แต่ถ้าเขียน test คุณจะไม่ต้องกังวลเลย เพราะถ้าโค้ดผิด อย่างน้อยก็มี test คอยเตือนว่าผิดตรงไหน นอกจากเขียน test บั๊กเองก็จบกัน T T อีกทั้งเวลาแก้โค้ด คุณจะไม่ต้อพะว้าพะวงว่ามานจะบึ้มตรงนู้นตรงนี้รึเปล่าเพราะบางส่วนเชื่อมกันอยู่ ไม่ต้องกลัวยังมี test คอยช่วยคุณอยู่ถ้ามันบึ้ม มันจะบอกคุณเอง

ข้อเสียก็คือ เสียเวลานั่นแแหละครับ ถ้าคุณเขียนโค้ดอย่างเดียว อาจใช้เวลา 4 วัน แก้เสร็จหาบั๊กเสร็จอีก 1-2 วันถ้าโชคดีเจอครบทั้งหมด ( หรือไปเรื่อยๆ เพราะหาไม่เจอ T T ) แต่ถ้าเขียน test ด้วยเวลา x 2 ไปครับ แต่ลด bug ไปเยอะแน่นอน จนถึงไม่มี แก้อีกนิดหน่อยเสร็จ (มีภูมิคุ้มกันดี) ซึ่งก็ใช้เวลาประมาณก็ 8 วัน แถมมีภูมิคุ้มกัน เวลาแก้ไขโค้ดด้วย นับว่าโอเคเลยครับ ส่วนข้อเสียของการเขียนคนเดียวก็ปวดหัวครับ เหมือนสลับโหมดการทำงานไปมา ตอนเขียน test มองแบบคลอบคลุม พอเขียนโค้ดมองแบบเจาะลึกสลับ ต้องมีสมาธิสูงครับ เหนื่อยมากด้วย

เขียนสองคน คนนึงเขียนโค้ด อีกคนนึงเขียน test
เป็นการทำงาน style pair-programming คนนึงเขียนโค้ด อีกคนเขียน test แล้วสลับตำแหน่งหน้าที่กัน อาจะทุกๆ หนึ่ง ชม. หรืออย่างไรก็แล้วแต่ อย่านานเกินจนดูโค้ดกันไม่รู้เรื่องก็พอ แบบนี้นี่โอเคเลยครับ คนเขียน test ก็เขียน test อย่างเดียว จำ test case ได้หมด คนเขียนโค้ดก็เขียนอย่างเดียว โดยให้คนเขียน test เป็นคนบอกเลยครับ เขียนอะไรยังไงบ้าง เราเขียนอย่างเดียวสบายครับ ไม่งั้นบางทีจะเขียนทีนั่งแช่อยู่คิดไม่ออกว่าเขียนยังไง หรือเขียนไปๆ แก้อยู่ตรงนั้นอ่ะ นาน นั่งคิดอยู่ว่าจะ work ไหม อีกทั้ง คนเขียน test รู้ครับว่าถ้าแก้เรื่องนี้ตรงแก้ที่ใดบ้าง บางทีคนเขียนโค้ดก็จำได้ไม่ค่อยครบหรอกครับ
ข้อดีคือ ทำให้การทำงานเร็วขึ้นกว่าการเขียนคนเดียวแน่นอนครับ เพราะแบ่งกันคิด แบ่งงานกันทำ สมองทำเรื่องๆ เดียว ไม่ปวดหัวมาก และทำงานได้ไว
ข้อเสียก็คือ ถ้าสองคนที่ทำงานด้วยกัน sync ได้ไม่ดีพอ หรือบางคนไม่เต็มร้อย เหม่อๆ ก็เจ๊งครับ ทำงานคนเดียวยังดีกว่าเลยบางช่วงเวลา แล้วถ้าอีกคนที่ทำงานด้วยกันประจำไม่อยู่ ไปไหนไม่รู้ ก็อาจต้องหาคนใหม่ ต้องจูนกันใหม่ หรือกลับไปโหมดอันเหน็ดเหนื่อยทำคนเดียว ในช่วงเวลาที่อีกคนไม่อยู่

ก็ยังมีอีกหลายเรื่องเกี่ยวกับ unit test ทั้งที่นึกออก และนึกไม่ออก ที่ผมไม่ได้เขียนลงไป ถ้าผมเขียนเรื่อง unit test ผิดพลาดยังไง ก็ขอโทษด้วยเพราะไม่ได้ศึกษาค้นคว้าข้อมูลมามากมาย ทั้งเรื่องของ unit test หรือการเขียนโปรแกรมในแบบที่ถูกต้องและควรจะเป็น ได้เรียนรู้นิดหน่อย ที่เหลือก็มาจากประสบการณ์ 2 เดือนนี้เองครับ

นี่ก็คือเรืองราวประสบการณ์ของผมที่มีต่อ Unit Test ครับ ^^

Unit Test เบื้องต้นกับ mocha node.js by

30
Apr
0

เริ่มต้นก็ขอเกริ่นก่อนนะครับว่า Unit Test คืออะไร สำหรับคนที่ยังไม่รู้นะครับ

Unit Test คือการทดสอบระบบหรือ function ของเราเองว่ามีการทำงานที่ถูกต้องหรือไม่ ซึ่งมีประโยชน์มากในการทำงาน เพราะถ้าเราเขียนโค้ดเพียงอย่างเดียว อาจจะมี test case บาง case ที่เรายังเขียนไม่ครบ ทำให้เกิด bug หรือทำงานไม่ถูกต้อง เกิด logic error ได้ ตรงจุดนี้ unit test จะช่วย check อีกรอบว่าโค้ดเราถูกต้องหรือไม่ อีกกรณีนึงก็คือ การ test ที่ยากลำบากที่ต้องทำหลายขั้นตอนกว่าจะ check ได้ unit test ก็ช่วยเราได้ โดยเขียนลำดับขั้นตอนตรงนั้นไว้ก่อนได้

ก็เริ่มต้นนะครับต้อง install unit test ก่อน

npm install mocha

จากนั้นต้องสร้าง folder test เอาไว้ก่อนเพราะ mocha จะใช้ได้กับ file ที่อยู่ใน folder test เท่านั้น

จากนั้นก็เริ่มต้นสร้าง file เขียน unit test กันได้เลย


var assert = require("assert");

function sum(a, b){
return a + b;
}


describe('CalculateTest', function(){
describe('#sum', function(){
it('3 + 2 = 5', function(){
assert.equal( 5, sum(3, 2));
assert.equal( 4, sum(3, 2));
});
});
});

อธิบายในส่วนของโปรแกรม
assert เป็น library ที่ต้องใช้ในการเปรียบเทียบ ยกตัวอย่างเช่น
assert.equal(a,b) ใช้เปรียบเทียบค่าว่าเท่ากันหรือไม่ ถ้าไม่เท่าจะ error
assert.notequal(a,b) ก็ตรงกันข้ามกับ equal

ส่วน describe เป็นเหมือนที่กำหนดว่าเราจะ test ไฟล์อะไร และ test function อะไร เหมือนเอาไว้บอกเราเฉยๆ ไม่ได้ผูกกับ function
นั้นโดยตรง

it เป็นตัวบอกว่าเราจะ test เทสเคสอะไร แล้วผลลัพธ์ที่ได้เป็นอะไร เขียนไว้เพื่อความเข้าใจ ควรเขียนนะครับ มิงั้นอาจลืมเลือนได้ว่าทำไรไว้ และก็ทุกอย่างควรจะเอาไว้ใน it นะครับเพราะ it จะรันสุดท้ายเสมอไม่ได้รันเรียงกันแบบ synchronous

จากนั้นก็จะ check ตรง assert ถ้าถูกทั้งหมดก็ผ่าน แต่ผิดซักอันนึงก็จะแสดง error ขึ้นมา
จากโค้ดตัวอย่าง

unit test

unit test

จะบึ้มลองเอาโค้ดด้านล่างนี้ออก
assert.equal( 4, sum(3, 2));
ออกจะได้แบบนี้ครับ

test ผ่าน

test ผ่าน

ด้านบนนี่เป็นแบบธรรมดาครับ ถ้าเป็นแบบที่ต้อง test แบบ asynchronous จะต้องมี function callback ด้วย และวางไว้ตำแหน่งที่เทสเคสนั้นทำจบแล้ว ประมาณ code ด้านล่างครับ


describe('#CreateRoomToServer()', function(){
var data = {};
var counter = 3;

it('should have Tom's room and increase the room counter', function(done){
Room.Room({ roomid: 1, roomname: 'monica'}, function(){
Room.Room({ roomid: 2, roomname: 'Bukkak'}, function(){
data.roomname = 'Tom';
Room.CreateRoomToServer( data, socket, counter, function(counter){
Redis_Client.hgetall("room:" + 3 + ":data", function(err, obj) {
Client.GetClient(Redis_Client, socket_test.id, function(reply){
assert.equal('Tom', obj.roomname);
assert.equal(3, reply.roomid);
assert.equal(4, counter);
done();
});
});
});
});
});
});
});

สังเกตว่าเราจะเอา done() ไว้จุดในสุด
เรื่อง unit test กับการใช้ mocha ก็ประมาณนี้ครับ

 เราชนะรอบ 4 | ยืมเงิน 3000 ด่วน | แอพกู้เงิน | แอพเงินด่วน | สินเชื่อออนไลน์อนุมัติทันที | Site Map | กู้เงินก้อน | กระเป๋าตัง | thisshop และ ยืมเงินฉุกเฉิน 5000 ด่วน