HomeAbout Me

給初學者的前端 Unit test 教學—— 以 React Testing Library 為例

By Nissen
Published in Web development
August 26, 2020
1 min read

給初學者的前端 Unit Test 教學(以React Testing Library 為例)

適合閱讀者:已經會寫React,但過去完全沒寫過「Component Unit Test」的人,本篇會透過React Testing Library 提供一些概略的介紹。希望閱讀完之後,更可以理解官方文件。

  • Unit test 是什麼? Unit test是「模組測試」,他可以針對程式的最小單元進行測試。所謂最小單元可能是某個程式、函式、組件等等。那在這個範例中,會用來測React的component。

  • React Testing Libray是什麼? 是一個可以方便的 React component 測試庫,特色是可以針對 DOM 的渲染結果進行測試,而不用去在意 React component 本身語法怎麼寫。

以一個按鈕為例,入門第一個 Unit Test測試

如果想要看範例檔案,請參考連結 當中的 button.jsbutton.test.js

怎樣算是一個正常的按鈕呢?

一個好的按鈕,通常表示「當點擊該按鈕被時,預期他會執行該做的事情(例如:執行函式)」

以外層來看(使用按鈕的那層)

當這裡的TodoButton被點擊時,我們會希望handleButtonClick()是真的有被呼叫到的。(在這裡它以onButtonClick的名字,被傳遞到了TodoButton裡面進去)

以元件本身來看(按鈕本身)

如果以元件本身來看,當TodoButton被點擊的時候,我們希望onButtonClick真的被呼叫

如何幫Button寫測試?

首先,在元件本身那層(TodoButton)開.test.js

每一個元件都應該要有測試,因此App.js也應該有個App.test.js的測試,但這邊先寫TodoButton的。

開始撰寫測試

首先要先將 testing-libraryjest-dom/extend-expectuserEventTodoButton 引用進來

  • jest-dom/extend-expect 是用來提供檢測用的 expect 函式(不懂的話可以直接看範例)
  • userEvent是用來模擬的使用者行為

解釋程式碼

  • const mockFunc = jest.fn() :宣告一個模擬的函式,之後會測試它是否有被呼叫
  • render() :將組建渲染出來,這樣後續才可以開始測試
  • screen.getByText('XXXX') 透過「文字」來獲取元素

注意:寫測試時,我們會希望測試是穩定性的,不會因為改動組件的一些內容,就需要導致測試重寫。因此在抓取元素的時候,會以終為始的去思考,直接思考「渲染後的結果」是什麼而去抓取,而不是透過getByComponent('TodoButton')之類的方式去抓取(雖然也沒有這個方法)。比如說,會從他已經被渲染成<button> Add todo</button> 的這個狀態去思考如何抓取,而不是嘗試去抓 <TodoButoon>

  • screen.debug() 如果想知道自己抓到了什麼,可以把它印出來
  • userEvent.click() 模擬使用者點擊的行為
  • expect(mockFn).toBeCalledTimes(1) 預期mockFunc函式再點擊後會被呼叫一次

開始執行測試

如果成功,就會得到結果

複習:撰寫一個測試的步驟

  1. 首先,要定義一下應該要測試什麼? 例如「一個正常的按鈕」,表示「當按鈕被點擊時,他應該觸發相關函式」
  2. 將組建引入,並且渲染組建:要先渲染出來,才能方便在後面抓取
  1. 利用選擇器抓取元素(要以渲染結果的樣子去思考),因此應該是

而不是像這樣

  1. 模擬使用者的動作,例如:點擊事件
  1. 測試一下預期的結果是否發生

常用語法

常用的選擇器

對於究竟要使用哪個選擇器,可以參考Which query should I use?

  • getByText:透過文字去抓取元素

  • getByLabelText:透過aria-label的屬性去抓取元素

  • getByDisplayValue:透過value的屬性抓取元素

  • getBytitle:透過title屬性抓取元素

常用的模擬行為

userEvent可以模擬使用者行為,可以參考User-Event事件

  • click(element,eventInit,options):模擬點擊事件
  • dbClick(element,eventInit,options):模擬雙擊事件
  • type(element,text,[options]):模擬打字事件
  • hover(element):模擬hover事件
  • paste(element,text,eventInit,options):模擬貼上事件

常用的測試函式

  • expect(mockFn).toBeCalledTimes(): 測試某函式被呼叫的次數

  • expect(mockFn).toBeCalledWith(參數):測試函式傳進去的「參數」是不是特定的值

  • expect().toHaveValue():測試某個元素是否有X值

  • expect().toHaveAttribute()

開始學習測試!

在擁有以上基礎概念之後,你可能還是有很多疑問,但你可以開始去閱讀以下文件了


Tags

測試react
Next Article
矽谷之旅(2):人焦慮的根源是什麼?

Nissen

Software Engineer

Topics

Software philosophy

Web development

Project

Free talk

Related Posts

為什麼我們需要閉包(Closure)?它是冷知識還是真有用途?
August 28, 2020
1 min
© 2023, All Rights Reserved.

Quick Links

Advertise with usAbout Us

Social Media