適合閱讀者:已經會寫React,但過去完全沒寫過「Component Unit Test」的人,本篇會透過React Testing Library 提供一些概略的介紹。希望閱讀完之後,更可以理解官方文件。
Unit test 是什麼? Unit test是「模組測試」,他可以針對程式的最小單元進行測試。所謂最小單元可能是某個程式、函式、組件等等。那在這個範例中,會用來測React的component。
React Testing Libray是什麼? 是一個可以方便的 React component 測試庫,特色是可以針對 DOM 的渲染結果進行測試,而不用去在意 React component 本身語法怎麼寫。
如果想要看範例檔案,請參考連結 當中的 button.js
和 button.test.js
一個好的按鈕,通常表示「當點擊該按鈕被時,預期他會執行該做的事情(例如:執行函式)」
當這裡的TodoButton被點擊時,我們會希望handleButtonClick()是真的有被呼叫到的。(在這裡它以onButtonClick的名字,被傳遞到了TodoButton裡面進去)
如果以元件本身來看,當TodoButton被點擊的時候,我們希望onButtonClick真的被呼叫
.test.js
每一個元件都應該要有測試,因此App.js也應該有個App.test.js的測試,但這邊先寫TodoButton的。
首先要先將 testing-library
、jest-dom/extend-expect
、userEvent
和 TodoButton
引用進來
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
函式再點擊後會被呼叫一次如果成功,就會得到結果
而不是像這樣
對於究竟要使用哪個選擇器,可以參考Which query should I use?
getByText:透過文字去抓取元素
getByLabelText:透過aria-label
的屬性去抓取元素
getByDisplayValue:透過value的屬性抓取元素
getBytitle:透過title屬性抓取元素
userEvent可以模擬使用者行為,可以參考User-Event事件
expect(mockFn).toBeCalledTimes(): 測試某函式被呼叫的次數
expect(mockFn).toBeCalledWith(參數):測試函式傳進去的「參數」是不是特定的值
expect().toHaveValue():測試某個元素是否有X值
expect().toHaveAttribute()
在擁有以上基礎概念之後,你可能還是有很多疑問,但你可以開始去閱讀以下文件了
Quick Links
Legal Stuff
Social Media