เข้าไปอ่านบทความเรื่อง Refactoring React จาก 8thlight มา
ทำการอธิบายเกี่ยวกับการ Refactor หรือการปรับปรุงโครงสร้างของระบบที่พัฒนาด้วย React
จาก React แบบปกติ ไปจนถึง ELM Architecture
มีความน่าสนใจและมีประโยชน์ต่อการพัฒนาระบบงานอย่างมาก
จึงทำการแปลและสรุปเพื่อเก็บไว้อ่าน
รวมทั้งฝึกการเขียน code และชุดการทดสอบไปในตัวอีกด้วย
ทำการแบ่งออกเป็น 2 ส่วน เนื่องจากมีรายละเอียดที่เยอะพอสมควรคือ
- การพัฒนาและทดสอบ React app
- การปรับปรุงโครงสร้างของ React app ให้เป็นไปตาม ELM Architecture
มาเริ่มในส่วนแรกกันดีกว่า
ในบทความเริ่มด้วยคำถามนี้ ซึ่งน่าสนใจมากคือ
How should i best test my React components ?
เรื่องของการทดสอบ React app และ Component นั้น
มันเป็นเรื่องที่ซับซ้อนสับสนวุ่นวายอย่างมาก
เนื่องจาก React เอง
มีทั้งเรื่องของ DOM (Document Object Model)
มีทั้งเรื่องของ State
มีทั้งเรื่องของการแสดงผล
มีทั้งเรื่องของ Life cycle
ซึ่ง React ได้นำส่วนต่าง ๆ เหล่านี้เข้ามาไว้ด้วยกัน
จะเรียกหรือใช้งานบ่อย ๆ คือ Component นั่นเอง
ดังนั้นการทดสอบ React นั้นจะต้องทดสอบในระดับของ Component กันเลย
พูดไปมันไม่เห็นภาพ มาเขียน code กันดีกว่า
โดยบทความนี้จะทำการสร้าง Simple Counter App
เป็น app ที่เพิ่มหรือลบตัวเลขเท่านั้น
ดังนั้นมีปุ่มบวก ปุ่มลบ และการแสดงตัวเลข
ซึ่งมันง่ายมาก ๆ
สามารถเขียนได้ดังนี้
จาก code นั้นเป็นอะไรที่ง่ายมาก ๆ
แต่ว่าถูก layer ของ React ซ่อนความซับซ้อนไว้เพียบ เช่น
- การทำ caching ค่าของ component
- การกำหนดค่าเริ่มต้นของ state จากตัวอย่างคือ counter
- ในส่วนของการ render ก็มีการจัดการข้อมูลจาก state รวมทั้ง callback ต่าง ๆ เพื่อจัดการกับ action/event ที่เกิดขึ้น คือ การกดปุ่มเพื่อเพิ่มหรือลดค่า counter
จากนั้นเพื่อให้เข้าใจมากขึ้น มาเขียนชุดการทดสอบกันดีกว่า
รวมทั้งทำให้เรามั่นใจอีกว่า
ถ้าเราต้องการแก้ไขโครงสร้าง และ reactor app ของเราแล้ว
จะไม่ทำให้การทำงานเปลี่ยนไป
หรือทำให้เรารู้ได้ทันทีว่าเกิดข้อผิดพลาดตรงส่วนไหนบ้าง
ไม่ใช่การทำไปเรื่อย ๆ หรือตามอารมณ์อีกต่อไป
การเขียน test สำหรับ React app นั้นมีทางเลือกเยอะมาก ๆ
ทั้ง Jest, Karma, Mocha, Chai และ Enzyme เป็นต้น
แต่ในบทความนี้เลือกใช้ Enzyme + mocha/chai
ซึ่ง Enzyme จะทำการจำลอง React component lifecycle ขึ้นมา
ทำให้เราสามารถทดสอบ React app/component ได้ง่ายขึ้น
มาเริ่มกันเลย
ก่อนที่จะเขียนสิ่งที่เราควรต้องคิดและออกแบบก่อนคือ
ต้องทำการทดสอบอะไรบ้าง ?
เนื่องจากเป็นการทดสอบในมุมมองของผู้ใช้งาน หรือ ผ่าน User Interface
ดังนั้นชุดการทดสอบจะประกอบไปด้วย
- ในหน้าจอประกอบไปด้วย 2 ปุ่ม คือ ปุ่มบวกและลบ
- ค่าเริ่มต้นต้องเป็น 0
- เมื่อกดปุ่มบวก ค่าต้องเพิ่มขึ้นมา 1
- เมื่อกดปุ่มลบ ค่าต้องลดลงไป 1
- เมื่อกดปุ่มบวกและลบไปมา ค่าที่แสดงต้องเป็นไปตามที่คาดหวัง
สิ่งที่ได้เรียนรู้จากการเขียนชุดการทดสอบด้วย Enzyme
ประกอบไปด้วย
- การติดตั้ง library ที่ต้องใช้งาน
- การใช้งาน Enzyme เพื่อจำลอง React component และทดสอบ component
- การใช้งาน Chai สำหรับการ assertion หรือตรวจสอบผลการทำงาน
เมื่อทำการเขียนชุดการทดสอบแล้ว ลองกลับมาดูระบบงานกันหน่อย
ถึงตรงนี้เราทำการทดสอบระบบงานในรูปแบบของ End-to-End testing ?
ตอนนี้เรากำลังทดสอบ framework หรือ framework testing หรือไม่ ?
ประเด็นคือเราผูกติดไปกับ framework มากเกินไปหรือไม่ ?
ส่วนการทำงานหลัก หรือ business logic อยู่ตรงไหน ?
เราสามารถแยกออกมาเพื่อทดสอบได้หรือไม่ ?
สิ่งที่เราควรให้ความสำคัญคือ
- การจัดการ state
- การเพิ่มหรือลดค่า
- การเชื่อมต่อ event ของแต่ละปุ่ม นั่นคือปุ่มบวกต้องเพิ่มค่า ปุ่มลบต้องลดค่า
- การแสดงผลตัวเลขของ counter
โดยสิ่งต่าง ๆ เหล่านี้ไม่ได้เกี่ยวข้องหรือใช้งาน lifecycle ของ React เลย
React มีหน้าที่เพียงเชื่อมโยงส่วนต่าง ๆ เข้าด้วยกัน (Integration)
ดังนั้นสิ่งที่เราต้องทำกันต่อไปคือ แยกส่วนการทำงานต่าง ๆ ออกจากกัน
จากนั้นทำการทดสอบในแต่ละส่วน
สุดท้ายนำมาผูกหรือเชื่อมต่อกันใน React app
โดยใน React community นั้นนิยมใช้งาน Redux
แต่ในบทความนี้ไม่ต้องการที่จะติดตั้ง Redux หรือ library อื่น ๆ เพิ่มเข้ามาอีก
เนื่องจากทำให้ระบบมีความซับซ้อนมากยิ่งขึ้น
และต้องการใช้งาน pure JavaScript เท่านั้น
โดย source code อยู่ที่ Github :: Up1 :: Learn React to ELM
ในบทความส่วนที่ 2 จะทำการอธิบายเกี่ยวกับ ELM architecture
และขั้นตอนการพัฒนาต่อไป
ซึ่งมันสนุกสนานและน่าสนใจอย่างมาก