เข้าไปอ่านบทความเรื่อง 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 ที่เพิ่มหรือลบตัวเลขเท่านั้น ดังนั้นมีปุ่มบวก ปุ่มลบ และการแสดงตัวเลข ซึ่งมันง่ายมาก ๆ สามารถเขียนได้ดังนี้ [gist id="fb3628de4f29dc88959b69334baac2ac" file="Counter.js"] จาก 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
ดังนั้นสิ่งที่เราต้องทำกันต่อไปคือ แยกส่วนการทำงานต่าง ๆ ออกจากกัน
จากนั้นทำการทดสอบในแต่ละส่วน สุดท้ายนำมาผูกหรือเชื่อมต่อกันใน React app โดยใน React community นั้นนิยมใช้งาน Redux แต่ในบทความนี้ไม่ต้องการที่จะติดตั้ง Redux หรือ library อื่น ๆ เพิ่มเข้ามาอีก เนื่องจากทำให้ระบบมีความซับซ้อนมากยิ่งขึ้น และต้องการใช้งาน pure JavaScript เท่านั้น โดย source code อยู่ที่ Github :: Up1 :: Learn React to ELMในบทความส่วนที่ 2 จะทำการอธิบายเกี่ยวกับ ELM architecture และขั้นตอนการพัฒนาต่อไป ซึ่งมันสนุกสนานและน่าสนใจอย่างมาก