June 27, 2016

ทำให้ Helper function ใน XCTest บอกตำแหน่งที่ Fail

หลังจากที่เราเขียนโค้ด test ไปเรื่อยๆ จะพบว่าหลายๆ case ที่ทดสอบนั้นจะมี Assertion ที่คล้าย หรือซ้ำกันเกิดขึ้น ทำให้บางทีเราจำเป็นต้องตัดสินใจแยกออกมาเป็น function ย่อยๆ ให้แต่ละ case ได้เรียกใช้งานร่วมกัน แต่ปัญหาก็คือ เมื่อ Test Fail เกิดขึ้นใน function เหล่านั้น เราไม่สามารถบอกได้ว่า test function ไหน fail เพราะ Xcode ดันไป highlight error ใน helper function แทน แทนที่จะ highlight ใน function test ที่เราเขียน

ยกตัวอย่างเวลาเขียนเขียน test UI แล้วสิ่งหนึ่งที่เรามักต้องทำซ้ำๆ กันก็คือ การทดสอบว่า element นั้นๆ มัน appear ออกมาหรือยัง ซึ่งเราก็สร้างออกมาเป็น function แยกต่างหาก ดังโค้ดต่อไปนี้

June 18, 2016

เริ่มเขียน Unit Testing ด้วย Swift

เท่าที่เคยสนทนากับหลายคนเกี่ยวกับการเขียน Unit Testing มา พบว่ามีคนอยู่ 2 กลุ่ม คือ

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

สำหรับคนกลุ่มที่ 2 ควรลองอ่านบทความนี้ดูครับ บทความนี้จะเสนอแนวคิดขั้นต้นในการเขียนโค้ดเพื่อให้เราสามารถ Test ได้

สำหรับการเขียน Test ให้กับ function ที่ไม่ได้มี dependency เลย นั้นทุกคนมักเขียนได้ เพราะมันค่อนข้างตรงไปตรงมา เช่น function ที่มีการรับค่าเข้าไปคำนวนได้ด้วยตัวเอง และ return กลับมาก็จบ แต่ที่เคยรู้มาคือปัญหาจะเกิดขึ้นตอนที่ function ที่ต้องการทดสอบนั้นมี dependency นี่แหละที่หลายคนมักจะงงกันว่าเราจะทดสอบมันยังไง

นี่คือ 4 เรื่องหลัก ที่เราต้องคิดถึงมันตลอดเวลาที่เราเขียนเทส และออกแบบ production code ของเรา

May 24, 2016

Monkey Test in iOS Project ให้ลิงลองเล่นแอพเราดูหน่อยซิ

มีคนกล่าวไว้ว่าการทดสอบซอฟท์แวร์ควรเป็นกิจกรรมที่เราต้องทำเป็นปกติตลอดเวลาที่เราพัฒนาซอฟท์แวร์ ซึ่งการทดสอบก็มีหลายระดับตั้งแต่ระดับฟังก์ชันการใช้งาน, UI หรือระดับโค้ดที่เขียนขึ้นมา อย่างน้อยก็เพื่อให้มั่นใจว่าซอฟแวร์ของเราไม่พังกลางทาง และทำงานได้ถูกต้องนั่นเอง

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

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

ในฝั่ง Android นั้นมี ลิง ของตัวเองสำหรับทำ stress test มาให้แล้ว แล้วในฝั่ง iOS ล่ะ ? อันที่จริง Instruments ที่ติดมากับ Xcode นั้นสามมารถทำ stress test ได้ แต่มันไม่ได้ถูกออกแบบมาให้เราใช้งานได้อย่างตรงไปตรงมาสำเร็จรูปแบบเดียวกับที่ Android มีสักทีเดียว

วิธีที่เราจะใช้ทำ stress test กับ iOS แอพของเราก็คือการเขียนโค้ด javascript แล้วสั่งมันสุ่มวนทำ Interaction ต่างๆ บนหน้าจอไปเรื่อยๆ เท่านั้นเอง

สำหรับหลายคน แค่คิดว่าจะต้องเขียน Javascript ก็รู้สึกไม่ค่อยสบายใจแล้ว ทำไมต้องมาหัดเขียน Javascript เพื่อทดสอบอีกล่ะ ? แล้วถ้าเขียนไม่เป็นล่ะจะทำยังไง ?

โชคดีที่โลกนี้ยังไม่สิ้นหวังไปซะทั้งหมด เพราะนาย Jonathan Penn ได้เขียน Javascript ชุดนี้ให้เรานำมาใช้ใน Instruments ได้เลย ... เอาล่ะ มาลองใช้กันสักหน่อยว่าเป็นยังไง

May 05, 2016

ซ่อน API ที่ซับซ้อนด้วย Builder Pattern

สำหรับตอนนี้ เป็นการเอาเหล้าเก่าในขวดใหม่มาเล่าต่อ สำหรับใครที่เคยเขียนภาษา​ Java หรือ Groovy มาก่อน ก็จะคุ้ยเคยกับคลาสที่ลงท้ายด้วยคำว่า Builder กัน รวมถึงวิธีใช้งานคลาสเหล่านี้ด้วย

ทีนี้ถึงคราวของ Swift บ้าง เรามาลองออกแบบ Builder Class ด้วย Swift อย่างง่ายๆ กัน

บน iOS ก็มี API บางตัวเวลาเราจะใช้งานมันได้ ก็ต้องสร้างนั่นสร้างนี่ 2-3 ขั้นตอน กว่าเราจะรวมร่างให้มันกลายเป็นสิ่งที่เราต้องการได้ ยกตัวอย่างเช่น การแสดง Alert ขึ้นมาบนหน้าจอ ที่เวลาเราจะสร้าง Alert ขึ้นมาสักอัน เราจำเป็นต้องรู้ก่อน ว่าเราจะใช้ UIAlertController สำหรับกำหนด title, message และใช้ UIAlertAction สำหรับสร้างปุ่มบน Alert และ action ที่จะเกิดขึ้นตามมาหลังจากกดปุ่มนั้น พอสร้างเสร็จก็เพิ่มลงไปใน UIAlertController และสุดท้าย ก็สั่งให้ UIViewController แสดง UIAlertController ที่กำหนดค่าเรียบร้อยแล้วขึ้นมาบนหน้าจอให้ User เชยชม

จะเห็นว่าเราต้องรู้จักขั้นตอนต่างๆ เพื่อที่เราจะสร้าง Alert ง่ายๆ ขึ้นมาสักอันหนึ่งตามที่ได้อธิบายไป และในคราวนี้ผมจะยกตัวอย่างการประยุกต์ใช้ Builder Pattern กับการสร้าง Alert ให้ดูกัน

March 27, 2016

เราจะสร้างประสบการณ์การขอสิทธิ์ (permission request) ในการเข้าถึงข้อมูลที่ดีให้แก่ผู้ใช้แอพได้อย่างไร?

อย่างหนึ่งที่จะทำให้ผู้ใช้ (user) รู้สึกหงุดหงิดเวลาใช้แอพของเราก็คือ การถูกถามขอสิทธิ์ (permission) ในการเข้าถึงข้อมูลสำคัญที่เป็นส่วนตัวของเรานั่นเอง ซึ่งสิทธิ์เหล่านี้ก็เช่นการขอเข้าถึง location service, camera, push notification, calendar, contact สาเหตุที่ขอก็เพื่อให้แอพสามารถทำงานได้อย่างเต็มความสามารถนั่นเอง แต่เมื่อไรก็ตามที่ผู้ใช้ไม่ให้สิทธิ์ที่แอพต้องการ แอพก็อาจทำงานได้ไม่เป็นไปตามที่ตั้งใจไว้ได้อย่างเต็มที่ และส่งผลให้แอปมีคุณค่าต่อผู้ใช้น้อยลง และสุดท้าย ผู้ใช้ก็ตัดสินใจลบแอปทิ้งในที่สุด :) 

ทำไมล่ะ? ลบทิ้งทำไม ลบทิ้งทั้งๆ ที่ยังไม่ได้ใช้ฟีเจอร์ที่ตั้งใจทำมาให้ใช้เลยเนี่ยนะ... น่าเศร้าใช่ไหม?

ส่วนใหญ่แล้ว Apple มักจะไม่ให้ขอสิทธิ์มั่วๆ อยู่แล้ว ถ้ามองในมุมของ iOS App เมื่อนักพัฒนาอัพโหลดแอพส่งขึ้นไปบน AppStore ก็จะมีเจ้าหน้าที่จาก Apple มาตรวจสอบแอพ รวมถึงตรวจสอบการร้องขอสิทธิ์ต่างๆ ว่าเหมาะสมหรือไม่ หากไม่เหมาะสมแอพนั้นจะไม่ได้รับอนุญาติให้ผู้ใช้คนอื่นดาวน์โหลดผ่าน AppStore ได้ ดังนั้นผู้ใช้ทางฝั่ง iOS ก็พอจะอุ่นใจได้บ้างว่า ที่แอพขอสิทธิ์เราไปน่ะ แอพได้เขียนอธิบายไว้ชัดเจน และไว้ใจได้แน่นอนว่าแอพจะไม่เอาข้อมูลเราไปใช้อย่างอื่นนอกจากที่เขียนบอกเราไว้แล้ว (ดังนั้นก่อนให้สิทธิ์ต่างๆ ควรอ่านให้ดีก่อนนะ)

การออกแบบหน้าจอการขอสิทธิ์ในการเข้าถึงข้อมูลส่วนตัวจากผู้ใช้นั้น ให้ focus อยู่ที่ 3 เรื่องหลักได้แก่ 1. เวลา, 2. บริบท (context) และ 3. ข้อความที่ใช้ขอสิทธิ์ เอาล่ะ มาดูกันว่าจะใช้ 3 สิ่งนี้ในการขอสิทธิ์ให้สำเร็จได้อย่างไร

March 06, 2016

Swift Lazy: เรามาขี้เกียจกันเถอะ

บทความนี้จะใช้ความขี้เกียจแสดงวิธีการเขียนโค้ดให้ดูดีมีประสิทธิภาพกันมากขึ้น โดยภาพรวมเราจะพูดถึง lazy variable และ lazy sequence

โจทย์
เรากำลังทำแอปที่ต้องแสดงรูป avatar ในขนาดที่ต่างๆ กันไป โดยเราจะมีขนาดหลักอยู่ 1 ขนาด และเมื่อใดก็ตามที่มีการเรียกใช้ avatar ในขนาดอื่น เราถึงจะ resize รูปเพื่อเอาไปใช้อีกที แบบนี้