ทำ unit testing ให้ component ใน react กัน [part1/2: Introduction]

Napat Suriyapun
THiNKNET Engineering
3 min readFeb 19, 2018

--

เตรียมตัว setup โปรเจ็กต์ เพื่อให้รันได้กันก่อนครับ

many thanks to : https://unsplash.com/photos/cXU6tNxhub0

เล่าให้ฟังเกี่ยวกับการทำ Test❗️

หากพูดถึงการ test นั้น น้องๆ ที่ยังเรียนไม่จบคงนึกถึงการเขียนโปรแกรมจนเสร็จแล้ว และเอาโปรแกรมไปให้ tester รุม จิ้มๆ และก็คอย report bug แน่ๆ เลย อยากบอกว่า ถ้าน้องคิดแบบนี้ เราก็เคยคิดเหมือนกัน..

ในวันที่เราโตขึ้น เราจะรู้ว่า การทำอย่างนั้น มันเป็นแค่ส่วนหนึ่งของการ test เอง จริงๆแล้ว พวกเราชาว programmer เนี่ย ก็ต้องเขียน code เพื่อ test เหมือนกันนะครับ

Dev testing คือการเขียน test เพื่อทดสอบ logic ของตัวเอง ว่ามันเป็นไปตามที่คิดหรือไม่ หลายคนอาจจะมองข้ามไป อาจจะคิดว่า ถ้าฉันคิดดีๆ จะต้องเขียนอะไรมาทดสอบไปทำไม แต่รู้มั้ย ว่าบางทีที่ต้องแก้งานในบางส่วน การที่มี test คลุมสิ่งที่ต้องการไว้ ทำให้ dev แก้งานง่ายขึ้นมาก (บางทีมันก็ทำให้ยากขึ้นนะ 555) แต่อย่างน้อยการมี test เป็นการประกันได้ว่า…

Developer เขียนโปรแกรมมาไม่ผิด กับสิ่งที่เขาคิดไว้

หลักการของการทำ Test โดยทั่วๆไป❗️

หากใครที่ไม่เคยทำ dev test มาก่อนเลย อาจจะงงๆ หน่อยว่าจริงๆแล้วการทำ test ของ code เราเนี่ย ความหมายมันคืออะไร ถ้าเอาทฤษฎีมานั่งอ่านกันคงต้องให้ไปอ่าน textbook เฉพาะทางไปหน่อย จริงๆแล้ว หลักการที่อยากให้รู้มีแค่ว่า

“สิ่งที่เราคาดหวัง กับสิ่งที่โค้ดของเราเขียนออกมา มันเหมือนกันหรือไม่ ” (จำหลักนี้ไว้เลย จำไม่ได้ปริ๊นท์ออกมาและกินเข้าไป 😆 )

ตัวอย่าง ที่ผมมักจะใช้สอนคนอื่นเวลาพูดถึง testcase คือฟังก์ชั่นการหารเลข divide(int a1, int a2) ซึ่งถ้าคนส่วนใหญ่จะ implement ก็น่าจะเขียนตามนี้

divide(int a1, int a2) {
return a/b;
}

ซึ่งมันก็ถูกนะ แต่มันถูกแค่ครึ่งเดียว.. แต่ถ้าผมตั้ง testcase มาให้ดังนี้ล่ะ 😲
กรณีที่ 1: ตัวเลขที่ตัวหารไม่เป็น 0 หารกัน เช่น divide(8, 2) ควรได้ 4 เป็นต้น
กรณีที่ 2: ตัวเลขที่ตัวหารเป็น 0 เช่น divide(8, 0) ควร return เป็น null หรืออะไรก็ว่าไป แต่ไม่ควรได้แบบ case ปกติ

พอบอกอย่างนี้ หลายคนถึงกับกุมขมับตัวเอง เออว่ะแม่ง เราลืมกรณีตัวส่วนเป็น 0 ได้ไงวะ 😞

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

ตรวจสอบซ้ำได้ที่ว่า คุณผู้อ่านลองนึกถึงกรณีที่มี testcase เยอะๆ ซัก 8 กรณี เรากำลังเขียนเพื่อทำให้โค้ดของเราทำงานในกรณีที่ 6 ถูกต้อง เราอาจเผลอไปแก้ให้กรณีที่ 3 ผิดโดยไม่รู้ตัวก็ได้

ถ้าเป็นคนไม่ละเอียด ไม่กลับมา test ซ้ำ ก็จะส่งผลให้โปรแกรมเรามี bug ไปแล้ว !!

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

แต่ข้อเสียของการทำ dev test มันก็มีนะครับ เช่น ถ้าเกิดโปรแกรมเราเปลี่ยน requirement นอกจากจะต้องเขียนโค้ดใหม่แล้ว ยังต้องเขียน test ใหม่ด้วยเช่นกัน หรือรวมถึง การทำ test มันค่อนข้างใช้เวลาพอสมควรเหมือนกันครับ

อาจจะดูยืดยาวสำหรับคนที่เคยเขียนโปรแกรมและเคยต้อง test มาบ้าง แต่ผมว่ามันน่าจะมีประโยชน์หากใครไม่เคยทำ test มาก่อนเลย ผมจะลองให้ทุกคน setup ตามสำหรับใครที่อยากจะ test react Component ครับ 😎

อุปกรณ์ที่จะใช้วันนี้❗️

  • create-react-app : โมดูลที่โคตรคูลที่สุดในการขึ้น react project เวลาจะทำโปรเจ็กต์อะไรหรือทดลองอะไรง่ายๆ ตัวนี้แนะนำเกือบทุกครั้งเลยครับครับ เพราะเจ้าตัวนี้ พอลงเสร็จ แทบจะสามารถเขียน react app ได้เลย รวมทั้งมันยังลง jest ซึ่งเป็น test runner ที่เราจะใช้วันนี้ด้วย
  • Enzyme : เป็นโมดูลที่เอาไว้สำหรับดูค่า Component Output ในเมื่อเราจะทำการ test component กัน เราจึงต้องมีตัวสำหรับดูค่า output ของ component ด้วย

การติดตั้งคร่าวๆ❗️

สำหรับมือฉมัง react คงไม่ได้มาอ่านบทความนี้ซักเท่าไร แต่ถ้าเป็นมือสมัครเล่นที่ไม่ได้มีความคล่องตัวสูง ผมจะทำการ guide ให้คร่าวๆ เพื่อที่จะได้เตรียมตัว และทำไปพร้อมกันได้นะครับ

  • หากใครที่มีโปรเจ็กต์ที่ถูกสร้างมาแล้วก็ข้ามไปเลย หากใครที่ไม่มี ก็ทำการ create-react-app เข้ามา จ้า
create-react-app <project_name>
  • ทำการติดตั้ง enzyme และ enzyme-adapter-react-<version> ตามตัวอย่างใน document ได้เลย และทำการ ‘configure adapter’ ด้วย เราควรจะได้ directory structure ตามนี้หากติดตั้งตามผม
yarn add --dev enzyme enzyme-adapter-react-16 [yarn user]npm install --save-dev enzyme enzyme-adapter-react-16 [npm user]

สำหรับ create-react-app นั้น การ configure adapter นั้น จะต้องทำที่ไฟล์ src/setupTests.js ไฟล์นี้ ถ้าคิดง่ายๆคือไฟล์ที่จะมารันก่อนที่จะรันไฟล์ test ทุกไฟล์ (พูดง่ายๆคือ ถ้าไม่มีไฟล์ setupTests คุณก็ต้องเอา code ตรงนี้ไปใส่ไฟล์ test ทุกไฟล์นั่นเอง)โดยสามารถ setup ได้ตามนี้เลย

ต่อไป เมื่อ setup ทั้งหมดเรียบร้อยแล้ว เราจะมาลองเขียน component ทดสอบก่อนเลย ทุกคนต้องผ่าน component นี้แน่นอน (ผมชอบเรียก Component นี้ว่า Component ครู 😱😱😱)
ในขั้นตอนนี้ ผมอยากให้ Copy Component และไฟล์ test วางก่อนเลยครับ

Counter Component

ถ้าลอง copy code เราไปวางทั้งหมด มันก็น่าจะได้ structure ประมาณนี้เนอะ

Figure 1: Directory Tree ปัจจุบัน

โดยเริ่มแรก ไฟล์ code และไฟล์ test ต้องอยู่ใน folder src ก่อนครับ (อย่าพึ่งย้ายไปที่อื่น มันน่าจะพังในตอนนี้)

ถ้าถึงขั้นตอนนี้ ถ้าหาก copy โค้ดผมไปรันได้อย่างถูกต้อง แล้วใช้คำสั่ง

yarn start [yarn user]
npm start [npm user]

เราควรได้หน้าตาของเว็บเราประมาณนี้

Figure 3 : Component ครูของทุกๆ คน

เราจะลองรันคำสั่งสำหรับ test ดู เมื่อรันคำสั่งนี้ เจ้าตัว create-react-app จะไปสั่ง test-runner ของมัน (Jest)ให้รันคำสั่งสำหรับ test ครับ

yarn test [yarn user]
npm test [npm user]

หากมันรันผ่าน และแสดงผลดังตัวอย่าง ก็ขอแสดงความยินดีด้วย คุณได้ไปต่อในขั้นต่อไปจ้า (หากติด error ลองส่งข้อความมาคุยกัน หรือลองหาๆ จาก google นะครับ 555)

Figure 2: Successfully test

สำหรับใครที่ได้ไปต่อ ขอเชิญไปต่อที่ ทำ unit testing ให้ component ใน react กัน [part 2/2: Component Test] นะครับ

สำหรับพื้นที่ Comment ด้านล่าง ผมอยากให้ทุกคน โดยเฉพาะคนที่ setup ไม่ได้ มาคุยถึงปัญหากัน ว่าติดอะไรอยู่ แล้วเราจะมาช่วยตอบกันครับ ♥
เพราะผมเข้าใจว่า ขั้นตอนที่ยากที่สุดในการทำอะไรซักอย่าง คือขั้นตอนเริ่มต้นนี่แหละครับ

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

ความรู้ยิ่งแบ่งยิ่งเพิ่มพูน ไม่เหมือนขนมที่ยิ่งแบ่งยิ่งลดลง :)

สวัสดีครับ 😍

--

--