LevelUp! Studio » bug https://blog.levelup.in.th Experience the new world. Fri, 26 May 2017 10:06:07 +0000 th hourly 1 http://wordpress.org/?v=3.8.1 [Unity3D] เราจะแก้ปัญหา NSURLErrorDomain error -1012 ใน WWW class ของ Unity 5 ใน iOS ได้อย่างไร? https://blog.levelup.in.th/2015/05/30/unity3d-%e0%b9%80%e0%b8%a3%e0%b8%b2%e0%b8%88%e0%b8%b0%e0%b9%81%e0%b8%81%e0%b9%89%e0%b8%9b%e0%b8%b1%e0%b8%8d%e0%b8%ab%e0%b8%b2-nsurlerrordomain-error-1012-%e0%b9%83%e0%b8%99-www-class-%e0%b8%82/ https://blog.levelup.in.th/2015/05/30/unity3d-%e0%b9%80%e0%b8%a3%e0%b8%b2%e0%b8%88%e0%b8%b0%e0%b9%81%e0%b8%81%e0%b9%89%e0%b8%9b%e0%b8%b1%e0%b8%8d%e0%b8%ab%e0%b8%b2-nsurlerrordomain-error-1012-%e0%b9%83%e0%b8%99-www-class-%e0%b8%82/#comments Sat, 30 May 2015 09:36:13 +0000 http://blog.levelup.in.th/?p=4376 เนื่องจากตอนนี้ Unity 5 ก็ออกมาสักพักใหญ่แล้ว แถมฟรีอีกตะหาก (ถ้ารายได้ไม่ถึงเป้า) เราก็ควรจะใช้ Unity 5 กันใช่ไหมครับ แต่ช่วงนี้ Unity 5 ได้ทำ bug (อันใหญ่หลวง) เอาไว้ นั่นคือหากเราใช้ WWW class เรียกไปที่ URL ใดๆ ที่เป็น https จะทำให้ไม่สามารถรับข้อมูลจาก URL นั้นๆ ได้เลย จะ WWW class จะแจ้ง error กลับมาว่า

The operation couldn’t be completed. (NSURLErrorDomain error -1012.)

ซึ่งเว็บเกมของผมเป็น HTTPS ทั้งหมดจึงกระทบเต็มๆ และบางคนอาจจะคิดว่าผมไม่พบปัญหานี้หรอก แต่ถ้าคุณต้องมีการเรียก Profile picture จาก  Facebook แล้วละก็ยังไงคุณก็จะถูกบังคับให้เรียกผ่าน HTTPS โดยอัตโนมัติ ถึง URL จะไม่ได้ระบุเป็น HTTPS  ก็ตาม เช่น http://graph.facebook.com/my_facebook_id/picture แต่สุดท้าย Facebook ก็จะ Redirect ไปยังที่อยู่รูปจริงๆ ที่เป็น HTTPS อยู่ดี และทำให้ไม่สามารถแสดงรูป profile facebook ได้ในที่สุด

จริงๆ แล้วปัญหานี้มีการแจ้งกันมาตั้งแต่เดือนมีนาคมแล้ว และ Unity ก็บอกว่าแก้ไปแล้วในเวอร์ชั่น 5.x.x แต่จนแล้วจนรอดก็ยังไม่ได้แก้จริงสักที ณ เวอร์ชั่นปัจจุบัน 5.0.1f ล่าสุดก็ยังไม่ได้แก้ ดังนั้นเราคงจะรอกันไม่ได้ ต้องหาวิธีแก้กันเอง โดยวิธีแก้ก็คือให้สร้างไฟล์ชื่อว่า CustomConnection.mm ขึ้นมา และใส่ code ด้านล่างลงไป

#include "Unity/WWWConnection.h"
@interface UnityWWWCustomRequestProvider : UnityWWWRequestDefaultProvider
{
}
+ (NSMutableURLRequest*)allocRequestForHTTPMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers;
@end
@implementation UnityWWWCustomRequestProvider
+ (NSMutableURLRequest*)allocRequestForHTTPMethod:(NSString*)method url:(NSURL*)url headers:(NSDictionary*)headers
{
NSMutableURLRequest* request = [super allocRequestForHTTPMethod:method url:url headers:headers];
// let's pretend for security reasons we dont want ANY cache nor cookies
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPShouldHandleCookies:NO];
return request;
}
@end
@interface UnityWWWCustomConnectionDelegate : UnityWWWConnectionSelfSignedCertDelegate
{
}
@end
@implementation UnityWWWCustomConnectionDelegate
- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse
{
// we dont want caching
return nil;
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
[super connection:connection didReceiveResponse:response];
}
@end
IMPL_WWW_DELEGATE_SUBCLASS(UnityWWWCustomConnectionDelegate);
IMPL_WWW_REQUEST_PROVIDER(UnityWWWCustomRequestProvider);

จากนั้นเซพไปที่ Assets/Plugins/iOS/CustomConnection.mm เท่านี้เป็นอันจบ ไม่ต้องไป set path ใดๆ เพิ่มเติม Unity จะจัดการของมันเองต่ออัตโนมัติ โดยหลักการทำงานของมันคือการแก้ไข class WWW ของ Unity ด้วยตัวเราเองผ่าน Plugin เพื่อ bypass cache บางอย่างที่ WWW ทำงานผิดพลาด สามารถอ่านรายละเอียดเพิ่มเติมได้ที่ Manual หน้านี้ครับ

ซึ่งวิธีแก้วิธีนี้ก็มาจากคนของ Unity นั่นแหละมาโพสต์บอกใน Forum ของเขาเองที่มีคนถาม แต่ด้วยเหตุผลประการใดก็ไม่อาจทราบได้ ตัว Unity หลักๆ กลับไม่ถูกแก้ไขเสียทีจนเราต้องมาแก้ไขเองนี่แหละ เท่านี้เป็นอันจบพิธีครับ :)

]]>
https://blog.levelup.in.th/2015/05/30/unity3d-%e0%b9%80%e0%b8%a3%e0%b8%b2%e0%b8%88%e0%b8%b0%e0%b9%81%e0%b8%81%e0%b9%89%e0%b8%9b%e0%b8%b1%e0%b8%8d%e0%b8%ab%e0%b8%b2-nsurlerrordomain-error-1012-%e0%b9%83%e0%b8%99-www-class-%e0%b8%82/feed/ 0
สรุปเนื้อหางาน Bug Day Bangkok 2013 https://blog.levelup.in.th/2013/03/31/bug-day-bangkok-2013-summarize%e0%b8%aa%e0%b8%a3%e0%b8%b8%e0%b8%9b%e0%b9%80%e0%b8%99%e0%b8%b7%e0%b9%89%e0%b8%ad%e0%b8%ab%e0%b8%b2%e0%b8%87%e0%b8%b2%e0%b8%99-bug-day-bangkok-2013/ https://blog.levelup.in.th/2013/03/31/bug-day-bangkok-2013-summarize%e0%b8%aa%e0%b8%a3%e0%b8%b8%e0%b8%9b%e0%b9%80%e0%b8%99%e0%b8%b7%e0%b9%89%e0%b8%ad%e0%b8%ab%e0%b8%b2%e0%b8%87%e0%b8%b2%e0%b8%99-bug-day-bangkok-2013/#comments Sun, 31 Mar 2013 09:06:15 +0000 http://blog.levelup.in.th/?p=2475 Openning Session

  • ฟังทีมงาน CP โม้ว่ากำลังวิจัยหุ่นยนต์ จะเอาไปใช้งานใน 7-Eleven 7000 สาขา
  • ชอบมาก Case Study จากอเมริกาที่ว่า “วางขวดเบียร์ข้างๆ ผ้าอ้อมแล้วยอดขายเพิ่มขึ้น 50%” เหตุเพราะผัวโดนเมียใช้ให้ไปซื้อผ้าอ้อม แต่ผู้ชายไม่มีเซ้นเรื่องซื้อของ เห็นอะไรใกล้มือกูหยิบแล้วรีบจากไปทันที(ผ้าอ้อมแบบแพงสุดเลยนะเออ) เพราะกูจะรีบไปกินเบียร์!!!

Fix UX Bug – Rawitat Pulam (Silapakorn University)

  • มี OS บางตัวที่เราต้องกด Start เพื่อสั่ง Shutdown (คุ้นๆ ไหม?)
  • การจะสร้างอะไรขึ้นมาซักอย่าง ต้องทำตามฐานความต้องการ user ไม่ใช่ความต้องการผู้สร้าง
  • จะสร้างอะไรซักอย่าง ได้ถามเค้ารึยังว่าเค้าทำไปให้ใครใช้?
  • หากมีความจำเป็นต้องเปลี่ยน UI จริงๆ เราควรจะคงความเคยชินของผู้ใช้ไว้บ้าง เช่น คงรูปๆ เดิม คงตำแหน่งๆ เดิม คงคำพูดแบบเดิม เพื่อให้ user ที่เคยชินแบบเก่ามีเวลาปรับตัวเข้ากับ UI ใหม่ได้ทัน ไม่ใช่หักดิบ ไม่เหมือนเดิมเลยแม้แต่น้อย
  • ถ้าต้องเลือกระหว่างแก้ UI ที่ชวนเข้าใจผิด (เช่นกด start เพื่อสั่ง shutdown) ให้เป็นแบบใหม่ กับการสละเอาความเคยชินผู้ใช้เดิมจนชินแล้ว สุดท้ายต้องถามก่อนว่าฐานลูกค้าส่วนไหนสำคัญกว่ากัน
  • UX ที่ดีต้องเกิดจากการใช้งานจริงของผู้ใช้ เป็นที่มาว่าทำไมเราต้องทำ TDD

Using TDD to understand legacy code – Dr.Suradet Jitprapaikulsarn (Naresuan University)

  • เป็นปรมาจารย์ด้าน TDD คนแรกๆ ของประเทศไทย ที่สอน TDD ให้กับนักศึกษาตั้งแต่ปีหนึ่ง!!
  • หัวใจสำคัญข้อแรกของการทำคือ “เขียนโค้ดใหม่เมื่อ test fail เท่านั้น” (Write new code only if a test has failed) – Kent Beck
  • ข้อสอง “จัดการโค้ดส่วนที่ซ้ำซ้อนให้หมดไปซะ” (Get rid of duplication) – Kent Beck
  • หนังสือที่น่าสนใจ:
    • K.Beck, Test-Driven Development by Example, Addison-Wesley, 2003
    • M. Features, Working Effectively with Legacy Code, Prentice Hall, 2004 (เป็นภาษา Python และมี legacy code ที่ bug เกิดจาก syntax ผิดด้วย – -”)
  • ใครว่า test ui ไม่ได้ test ได้แค่มันยากกกก เช่น บริษัทแห่งหนึ่งทำเว็บให้บริษัทขายยา 2 แห่งที่เป็นคู่แข่งกัน core code เหมือนกัน เปลี่ยนแค่ template แต่เสือกสลับ template ผิด ทำให้บริษัทขายยาเข้าใจว่าบริษัทขายยาคู่แข่งไปขโมยข้อมูลของตนมา เรื่องราวโดนฟ้องร้องใหญ่โต

Test Driven Development 3.0 – Twin Panichsombat (Siam Chamnankit)

  • BDD คือการมองจากภาพใหญ่ไล่เข้าไปยังจุดเล็กสุด (unit) ตรงข้ามกับ TDD ที่เริ่มจากจุดเล็กสุด (unit-test) ไล่ออกมาข้างนอก
  • BDD คือ superset ของ TDD มันคือการทำให้เขียน TDD เป็นเรื่องสนุก
  • BDD ยังช่วยให้ Business Analytic อ่าน spec ได้เข้าใจเป็นภาษาคนอีกด้วย ให้ BA มาช่วยเขียน spec ง่ายขึ้นมาก
  • การใช้งาน BDD จำเป็นต้องมี tools ที่ design มาเพื่อการนี้โดยเฉพาะ ใช้ tools เดิมแบบตอนเขียน TDD ไม่ได้
  • Behal เป็น framework สำหรับใช้งาน BDD ในภาษา PHP
  • Rspec สำหรับ Ruby on Rails

Big Data and How to test it – Somkiat Puisungnoen (Siam Chamnankit)

  • Big Data ก็คือการทำงานกับข้อมูลเยอะๆ นั่นแหละ มีขนาดตั้งแต่หลาย GB ขึ้นไป ใช้ mySQL query แล้วมันช้า ต้องรอเป็นวัน
  • ตัวอย่างการใช้งาน Big Data เช่น Modern Information Infrastructure, Semantic Technology, The Logical Data Warehouse, NoSQL DBMS, In-Memory Computing
  • การจัดการกับ Big Data คือการเลือก tools ที่ทำงานเฉพาะทางเข้ามาทำงานแทนแค่บางส่วน ไม่ได้มาแทนที่ mySQL สุดท้ายเราจะยังคงต้องใช้ mySQL อยู่ต่อไป
  • ถ้าปริมาณข้อมูลที่ใช้งานปัจจุบัน คุณสามารถใช้งานได้อย่างปกติสุข รวดเร็ว พอใจอยู่แล้ว คุณก็ไม่จำเป็นต้องกระเสือกกระสนที่จะพยายามใช้ tools สำหรับ Big Data ต่างๆ เพ
  • กฎที่น่าสนใจของ Big Data คือเราควรต้องดูแลข้อมูลเพียงชุดเดียว เพื่อความง่ายในการจัดการ
  • ข้อมูลจะมีค่าเมื่อเวลาผ่านไป ห้ามลบทิ้งถ้าเป็นไปได้
  • ซอฟต์แวร์ที่น่าสนใจสำหรับการประมวลผลข้อมูลแบบ Real time: Storm

จบละครับ :)

]]>
https://blog.levelup.in.th/2013/03/31/bug-day-bangkok-2013-summarize%e0%b8%aa%e0%b8%a3%e0%b8%b8%e0%b8%9b%e0%b9%80%e0%b8%99%e0%b8%b7%e0%b9%89%e0%b8%ad%e0%b8%ab%e0%b8%b2%e0%b8%87%e0%b8%b2%e0%b8%99-bug-day-bangkok-2013/feed/ 0
วิธีแก้ปัญหาเมื่อตาราง InnoDB ไม่สามารถ alter, optimize, dump ได้เลย https://blog.levelup.in.th/2011/06/30/how-to-deal-with-innodb-table-cannot-alter-optimize-dump-problem%e0%b8%a7%e0%b8%b4%e0%b8%98%e0%b8%b5%e0%b9%81%e0%b8%81%e0%b9%89%e0%b8%9b%e0%b8%b1%e0%b8%8d%e0%b8%ab%e0%b8%b2%e0%b9%80%e0%b8%a1/ https://blog.levelup.in.th/2011/06/30/how-to-deal-with-innodb-table-cannot-alter-optimize-dump-problem%e0%b8%a7%e0%b8%b4%e0%b8%98%e0%b8%b5%e0%b9%81%e0%b8%81%e0%b9%89%e0%b8%9b%e0%b8%b1%e0%b8%8d%e0%b8%ab%e0%b8%b2%e0%b9%80%e0%b8%a1/#comments Thu, 30 Jun 2011 15:51:56 +0000 http://blog.levelup.in.th/?p=1126 เนื่องจากช่วงนี้มีปัญหาโลกแตกที่ตาราง InnoDB อยู่ๆ ก็เกิด alter, optimize, dump ไมได้เลยซักกะอย่าง มันจะบอกว่า “MySQL server has gone away” หรือ “Error 2013: Lost connection to MySQL server during query when …” ซึ่งช่างเป็น error ที่สื่อความหมายได้ดีเยี่ยมเสียจริง! ไปดูใน log error ก็ฟ้องว่า thread MySQL ตายกลางทาง กรุณา submit bug ไปให้ MySQL เอ่อ… พอสั่ง Check table มันก็บอกว่าปกติดี เอะยังไง! สุดท้ายเนื่องจากจนปัญญาจึงต้องมานั่ง query ทีละ rowๆ ออกมาใส่ตารางใหม่ที่โครงสร้างเหมือนเดิม ซึ่งได้ผลดังนี้

1. ตารางที่ query มันใหญ่มาก! ไม่สามารถสั่ง INSERT INTO user2 (SELECT * FROM user) ได้ตรงๆ เลยแบบง่ายๆ

2. ลองสั่ง INSERT INTO user2 (SELECT * FROM user LIMIT 0,1000) ไรทำนองนี้ก็ไม่ให้อีก! มันฟ้องว่า subquery ไม่ support limit เวรจริงๆ ครับ 55

3. ลองใช้ php ช่วย คือสั่ง SELECT * FROM user WHERE user_id NOT IN (SELECT user_id FROM user2) LIMIT 0,1000 แล้วค่อยเอา user_id ที่ได้มา query ต่อเป็น “INSERT INTO user2 (SELECT * FROM user WHERE user_id IN(“.implode(‘,’, $a_user_id).”))” ก็ยังไม่ได้เพราะแต่ละ row มันใหญ่มาก กว่าจะเสร็จก็ช้ามากๆ

4. สุดท้ายจึงได้เป็น SELECT user_id FROM user WHERE user_id NOT IN (SELECT user_id FROM user2) LIMIT 0,1000 แล้วต่อด้วย ”INSERT INTO user2 (SELECT * FROM user WHERE user_id IN(“.implode(‘,’, $a_user_id).”))” เหมือนเดิม ก็ใช้ได้ละครับ :)

5. รันไปซักพักพบ “MySQL Server has gone away” อีกแล้ว – -” จึงค่อยๆ ลด Limit มาเหลือ 1 ก็ยังพัง และค่อยๆ ลอง SELECT * FROM user WHERE id=1 ไปเรื่อยๆ โดยเปลี่ยน * เป็น field ในตารางที่มีทีละ field ปรากฏว่าก็เจอ field เจ้าปัญหาจนได้ เป็น Text field นี่เอง! ซึ่งเราไม่สามารถแม้กระทั่งสั่ง DELETE FROM user WHERE id=1 ช่างโหดร้ายยิ่ง!

6. ต่อมาจึงต้องใส่ offset เพื่อ skip row ที่มีปัญหาไป แล้วก็รันๆ ไปซักพักอีกก็เจออีก สรุปว่าข้อมูล user แสนคน เจอ row ที่มีปัญหาทั้งหมด 5 row มันไปทำอีท่าไหนถึงพังก็ไม่อาจทราบได้ และตอนนี้ก็สามารถกลับมาใช้งานได้ตามปกติซะที :)

]]>
https://blog.levelup.in.th/2011/06/30/how-to-deal-with-innodb-table-cannot-alter-optimize-dump-problem%e0%b8%a7%e0%b8%b4%e0%b8%98%e0%b8%b5%e0%b9%81%e0%b8%81%e0%b9%89%e0%b8%9b%e0%b8%b1%e0%b8%8d%e0%b8%ab%e0%b8%b2%e0%b9%80%e0%b8%a1/feed/ 0
Test Driven Development (TDD) https://blog.levelup.in.th/2011/03/30/test-driven-development-tddtest-driven-development-tdd/ https://blog.levelup.in.th/2011/03/30/test-driven-development-tddtest-driven-development-tdd/#comments Wed, 30 Mar 2011 16:05:19 +0000 http://blog.levelup.in.th/?p=923 ผมไปฟังพี่ @roofimon ในวัน Bug Day มา เลยเอามาแชร์ต่อ เนื่องจากปัญหาการ Develop งานแบบเก่าอาจเกิดปัญหาดังต่อไปนี้

  • ฝั่ง Programmer เขียน code มาแล้วส่งมาให้ Tester ปรากฏว่า Bug ตรึม Tester ก็โวยวายใส่ Programmer
  • Tester รายงานว่ามี Bug อะไรบ้างกลับไปให้ Programmer แล้วปรากฏว่า Programmer แก้ bug ตัวใหม่เสร็จ Bug ตัวเก่ากลับปรากฏขึ้นมาซ้ำทั้งๆ ที่แก้ไปแล้ว
  • เมื่อ Bug เกิดขึ้นหนึ่งครั้ง หาต้นตอของ Bug ยาก ไม่รู้เริ่มผิดตั้งแต่ตรงไหน ต้องมาพิมพ์ print ไล่ code ทีละส่วน
  • “เครื่องผมไม่เห็น bug เลย ทำไมเครื่องคุณ bug ล่ะ Test ยังไงเนี่ย”
  • “เมื่อวานยังไม่ Bug เลย ทำไมวันนี้มันพังตอน present ให้หัวหน้าดูได้(วะ)เนี่ย”
  • เมื่อเกิดปัญหาเช่น performance หรือต้องมีการแก้ไข Code ส่วน Core หลักที่ใช้งานทุกๆ ที่ จะไม่สามารถมั่นใจได้เลยว่าแก้ไปแล้ว Code เก่าที่อื่นจะ Bug หรือไม่
  • อื่นๆ อีกมากมาย

Test Driven Development (ต่อไปนี้ขอเรียก TDD) จะเข้ามาช่วยแก้ปัญหา หรือบรรเทาปัญหาเหล่านี้ลงได้ ซึ่งต้องมีการเขียน Unit Test (การทดสอบการทำงานของ Code ด้วย Code ทำให้สามารถสั่งรันแบบ automatic ได้) โดยมีหลักการดังนี้

  1. บังคับเขียน Unit Test ก่อนลงมือ Code จริง โดยพูดง่ายๆ ว่า Test = Requirement โดย Programmer ต้องเป็นผู้ลงมือเอง คนเดียวกับคนที่เขียน Code นั่นแหละ
  2. การจะเขียน Test ก่อนลงมือ Code ได้จำเป็นต้องรู้โครงสร้าง code มาก่อนแล้วคร่าวๆ โดยเฉพาะ Input และ Output ที่ต้องการ ส่งผลให้เกิดการวางแผนล่วงหน้าก่อนการเขียน Code
  3. ถ้าเขียน Test ไม่ได้ หรือเขียน Test ยาก แสดงว่า Code ของคุณยังไม่สละสลวยพอต่อการ Test (คำกล่าวจากท่าน dean4j) หรือพูดง่ายๆ ว่า Code คุณห่วยนั่นเอง! ต้องแก้ที่ Code ไม่ใช่ที่ Test
  4. การเขียน Test หลักๆ แล้วต้องมีมาก-น้อยแค่ไหนก็ขึ้นอยู่กับ Requirement ของลูกค้านั่นแหละ อย่าไปคิดแทนลูกค้า! เพราะเค้าอาจไม่ได้เห็นดีด้วยกับสิ่งที่เราเพิ่มเข้าไปเองทีหลัง
  5. เมื่อเขียน Test เสร็จแล้วค่อยลงมือ Code ตามปกติ เมื่อเขียนเสร็จก็สั่งรัน Test ได้เลยว่าผิด-ถูกอย่างไร
  6. เขียน Test เป็น Moduleๆ ก่อน และต้องเขียน Test ระหว่าง Module ที่มีการทำงานข้ามกันไปมาแยกกันด้วย เพราะเมื่อเกิดปัญหาจะได้รู้ว่า Bug ที่ Module ไหน หรือ Bug ตอนระหว่างจะคุยกันระหว่าง Module
  7. จะมี CI เป็น server ที่ set environment ไว้สำหรับ test แล้วคอยดึง code ไป test ทุกๆ วันให้แบบอัตโนมัติ เพื่อทดสอบว่า Code ที่เขียนขึ้นใหม่ไม่กระทบของเก่า โดย Programmer ไม่จำเป็นต้องสั่งเองให้เหนื่อย

บางคนอาจสงสัยว่า ทำไมเขียน Test ทีหลังไม่ได้ ทำไมต้องเขียนก่อน หรือให้ Programmer คนอื่นเขียน test ตามที่หลังได้ไหม อันนี้จากประสบการณ์ส่วนตัวของผมเอง จะมีข้อเสียดังนี้

  1. ถ้ามี Programmer คนอื่นมาเขียน Test ที่ตัวเองไม่ได้เป็นคน Code เอง ก็จะไม่อาจรู้ได้ว่า Code ส่วนไหนมีความสำคัญมากน้อยเพียงใด ที่สำคัญ Programmer ที่เป็นคน Code สามารถทิ้งขยะก้อนโตที่อ่านยากๆ ฝากเอาไว้อย่างไม่ใยดีได้อย่างง่ายดาย
  2. ถ้าเป็น Code ตัวเอง แต่มาเขียน Test ทีหลัง ปัญหาที่เกิดก็ง่ายมากครับ “ก็มันเสร็จแล้วทำไมต้องเขียน Test อีก” พูดง่ายๆ ว่าขี้เกียจนั่นเองครับ 55 และถ้าต้องเขียน code ที่ไม่ได้ Design เผื่อสำหรับ Test แต่แรกนี่ก็เป็นความยากระดับมหาโหดเลยทีเดียว
  3. บางครั้งการเขียน Code Programmer มักจะเผื่อโน่นนี่ที่ไม่ได้ใช้เอาไว้หลากหลายมาก เมื่อเขียน Test และต้องเขียนให้ได้ Coverage 100% ก็จะยิ่งขี้เกียจหนัก เช่นมี if สัก 10 ทีก็ไม่ไหวแล้ว ถ้าเขียน Test ก่อน ด้วยความขี้เกียจของ Programmer เองจะทำให้มี Test เฉพาะที่จำเป็นเอง และ Code ส่วนที่ไม่ค่อยจำเป็นจะไม่ถูกเขียนขึ้นตั้งแต่แรก ประมาณว่า “ถ้ามันไม่ได้ใช้แล้วเขียนเผื่อไว้ทำไมให้เหนื่อย”
  4. หากเขียน Test ทีหลัง และ Code นั้นเป็น Code ที่ถูกสร้างขึ้นมานานแล้ว Programmer แม้จะเป็นคนเขียนเองก็ตาม จะเกิดอาการ “ลืม” ได้ง่ายมากๆ ครับ พอลืมก็ต้องมานั่งอ่านทำความเข้าใจ Code อีกรอบ เสียเวลามากๆ เลยทีเดียว

ทีนี้เรามาสรุปข้อดีว่าถ้ามี Unit Test ที่เขียนก่อนแล้วจะมีผลดีอย่างไรบ้าง

  1. แม้ว่าจะต้องเสีย Overhead เรื่องเวลาไปก่อนกับการเขียน Test แต่เมื่อมีการกลับมาแก้ภายหลังแล้วจะสามารถแก้ได้อย่าง “มั่นใจว่าจะไม่ Bug” มากขึ้นมากเลยละครับ เพราะมีตัว Test ที่สั่ง run ปุ๊บก็รู้เลยว่ากระทบ Code เก่าหรือไม่ ทำให้ประหยัดเวลาในการ Test เรื่องเดิมๆ ของ Tester ไปได้มากด้วย ลดงาน Tester ได้เยอะครับ
  2. สามารถระบุตำแหน่งที่เกิด Bug ขึ้นได้อย่างง่ายดายด้วย Test ที่เขียนไว้ การใช้เวลาในการหา Bug จะลดลงเป็นอย่างมาก
  3. เมื่อเกิดการเปลี่ยน Environment การใช้งานขึ้น เช่นย้ายไปรันที่เครื่องอื่น แค่สั่งรัน Test ก็จะรู้ต้นตอของปัญหาได้ไม่ยากเลย ลดปัญหาเถียงกันไปเถียงกันมาว่าใครผิดระหว่าง Tester และ Programmer ลงได้มาก
  4. ถ้ามีการแก้ไข code แม้เพียงเล็กน้อยในสถานการณ์กระชั้นชิดเช่นการ present ให้หัวหน้าดู แก้เสร็จก็รัน Test ได้เลย ก็จะลดความเสี่ยงหน้าแตกต่อหน้าหัวหน้าได้มาก
  5. เมื่อมีการใช้งานไปสักระยะ และมีความจำเป็นต้องแก้ไข Code ส่วน Core หรือต้องมีการปรับปรุง performance ก็สามารถมั่นใจได้ว่าแก้ไขไปแล้ว performance ดีขึ้นโดยไม่ใช่ว่าทำให้ bug เพิ่มขึ้นตาม
  6. Code ที่ออกมามีคุณภาพสูง อ่านง่าย เพราะไม่งั้นเขียน Test ไม่ได้ เมื่อมีการส่งต่อ Code ให้คนอื่นทำต่อก็จะเกิดปัญหาน้อยลง
  7. เมื่อ Programmer คนอื่นต้องการศึกษาวิธีการใช้งาน module ใดๆ ว่าต้องส่งค่า Input อย่างไรเข้าไป และจะได้ Output อย่างไรออกมาก็สามารถดูจาก Test ที่เขียนไว้ได้เลย สามารถ Copy ตัวอย่าง Code จาก Test มาปรับแก้ได้ทันที ดีกว่าอ่าน Manual ตัวหนังสือเยอะๆ เสียอีก :)

สรุปว่าเมื่อ Programmer เขียน Test แล้ว Code ก็จะอ่านง่ายขึ้น Bug จะน้อยลง Tester จะงานน้อยลง Programmer แก้ Bug ได้เร็วขึ้น Tester ก็จะด่า Programmer น้อยลง ลดความขัดแย้งระหว่าง Programmer-Tester และ Programmer-Programmer(ที่ทำงานร่วมกัน) ลงได้มาก และองค์กรจะสงบสุข ยอดขายพุ่งกระฉูด และโลกก็จะสงบสุข สวัสดีครับ :)

]]>
https://blog.levelup.in.th/2011/03/30/test-driven-development-tddtest-driven-development-tdd/feed/ 2
Bug IE6 javascript location และการแก้ไข https://blog.levelup.in.th/2010/01/28/bug-ie6-javascript-locationbug-ie6-javascript-location-%e0%b9%81%e0%b8%a5%e0%b8%b0%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b9%81%e0%b8%81%e0%b9%89%e0%b9%84%e0%b8%82/ https://blog.levelup.in.th/2010/01/28/bug-ie6-javascript-locationbug-ie6-javascript-location-%e0%b9%81%e0%b8%a5%e0%b8%b0%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b9%81%e0%b8%81%e0%b9%89%e0%b9%84%e0%b8%82/#comments Thu, 28 Jan 2010 14:03:13 +0000 http://blog.levelup.in.th/?p=354 เป็นบั๊กที่เกิดเฉพาะกับ browser เจ้าปัญหาเช่นเคย คราวนี้เป็น bug เกี่ยวกับการเปลี่ยนหน้าด้วย javascript

ซึ่งปกติเราจะทำกันอย่างนี้

document.location.href = “http://www.levelup.in.th/”;

แต่ปรากฎว่ามันใช้ไม่ได้ใน IE6! หลังจากหาข้อมูลมาได้ สรุปแล้วเราต้องเพิ่ม
window.event.returnValue = false;

เข้าไปใน code ด้วย แต่คราวนี้ดันทำให้ browser

try {

document.location.href = site_url(u);

window.event.returnValue = false;

}catch(e){}

]]>
https://blog.levelup.in.th/2010/01/28/bug-ie6-javascript-locationbug-ie6-javascript-location-%e0%b9%81%e0%b8%a5%e0%b8%b0%e0%b8%81%e0%b8%b2%e0%b8%a3%e0%b9%81%e0%b8%81%e0%b9%89%e0%b9%84%e0%b8%82/feed/ 0