跳至主要內容

設定

React 測試函式庫 不需要任何設定即可使用。然而,您可以設定測試框架來減少一些樣板程式碼。在這些文件中,我們將示範如何設定 Jest,但您應該可以使用任何測試框架來做類似的事情(React 測試函式庫不要求您使用 Jest)。

全域設定

在您的全域測試設定中新增選項可以簡化個別檔案中測試的設定和拆解。

自訂渲染

定義一個包含全域上下文提供者、資料儲存等的自訂渲染方法通常很有用。為了使其在全域可用,一種方法是定義一個從 React Testing Library 重新匯出所有內容的實用程式檔案。您可以在所有導入中用這個檔案取代 React Testing Library。請參閱下方,了解如何在不使用相對路徑的情況下存取您的測試實用程式檔案。

下面的範例使用 renderwrapper 選項來設定資料提供者。

my-component.test.jsx
- import { render, fireEvent } from '@testing-library/react';
+ import { render, fireEvent } from '../test-utils';
test-utils.jsx
import React from 'react'
import {render} from '@testing-library/react'
import {ThemeProvider} from 'my-ui-lib'
import {TranslationProvider} from 'my-i18n-lib'
import defaultStrings from 'i18n/en-x-default'

const AllTheProviders = ({children}) => {
return (
<ThemeProvider theme="light">
<TranslationProvider messages={defaultStrings}>
{children}
</TranslationProvider>
</ThemeProvider>
)
}

const customRender = (ui, options) =>
render(ui, {wrapper: AllTheProviders, ...options})

// re-export everything
export * from '@testing-library/react'

// override render method
export {customRender as render}

注意

當嘗試覆寫上述範例中的具名匯出時,低於 7 的 Babel 版本會擲回錯誤。請參閱#169 和下方的解決方法。

Babel 6 的解決方法

您可以使用 CommonJS 模組而不是 ES 模組,這應該在 Node 中運作

test-utils.js
const rtl = require('@testing-library/react')

const customRender = (ui, options) =>
rtl.render(ui, {
myDefaultOption: 'something',
...options,
})

module.exports = {
...rtl,
render: customRender,
}

新增自訂查詢

注意

一般來說,您不需要為 react-testing-library 建立自訂查詢。如果您確實使用它,您應該考慮新的查詢是否鼓勵您以使用者為中心的方式進行測試,而不會測試實作細節。

您可以按照自訂查詢文件中所述定義自己的自訂查詢,或透過 buildQueries 協助程式。然後,您可以使用 queries 選項在任何渲染呼叫中使用它們。為了使自訂查詢在全域可用,您可以將它們新增至您的自訂渲染方法中,如下所示。

在下面的範例中,建立了一組新的查詢變體,用於依 data-cy 取得元素,這是 Cypress.io 文件中提到的「測試 ID」慣例。

custom-queries.js
import {queryHelpers, buildQueries} from '@testing-library/react'

// The queryAllByAttribute is a shortcut for attribute-based matchers
// You can also use document.querySelector or a combination of existing
// testing library utilities to find matching nodes for your query
const queryAllByDataCy = (...args) =>
queryHelpers.queryAllByAttribute('data-cy', ...args)

const getMultipleError = (c, dataCyValue) =>
`Found multiple elements with the data-cy attribute of: ${dataCyValue}`
const getMissingError = (c, dataCyValue) =>
`Unable to find an element with the data-cy attribute of: ${dataCyValue}`

const [
queryByDataCy,
getAllByDataCy,
getByDataCy,
findAllByDataCy,
findByDataCy,
] = buildQueries(queryAllByDataCy, getMultipleError, getMissingError)

export {
queryByDataCy,
queryAllByDataCy,
getByDataCy,
getAllByDataCy,
findAllByDataCy,
findByDataCy,
}

然後,您可以透過傳遞 queries 選項來覆寫和附加新的查詢。

如果您想要全域新增自訂查詢,您可以透過定義您的自訂 renderscreenwithin 方法來執行此操作

test-utils.js
import {render, queries, within} from '@testing-library/react'
import * as customQueries from './custom-queries'

const allQueries = {
...queries,
...customQueries,
}

const customScreen = within(document.body, allQueries)
const customWithin = element => within(element, allQueries)
const customRender = (ui, options) =>
render(ui, {queries: allQueries, ...options})

// re-export everything
export * from '@testing-library/react'

// override render method
export {customScreen as screen, customWithin as within, customRender as render}

然後,您可以像使用任何其他查詢一樣使用您的自訂查詢

const {getByDataCy} = render(<Component />)

expect(getByDataCy('my-component')).toHaveTextContent('Hello')

使用測試工具設定 Jest

為了使您的自訂測試檔案可以在您的 Jest 測試檔案中存取,而無需使用相對導入(../../test-utils),請將包含該檔案的資料夾新增至 Jest moduleDirectories 選項。

這將使 test-utils 目錄中的所有 .js 檔案都可以導入,而無需 ../

my-component.test.js
- import { render, fireEvent } from '../test-utils';
+ import { render, fireEvent } from 'test-utils';
jest.config.js
module.exports = {
moduleDirectories: [
'node_modules',
+ // add the directory with the test-utils.js file, for example:
+ 'utils', // a utility folder
+ __dirname, // the root directory
],
// ... other options ...
}

如果您使用的是 TypeScript,請將此合併到您的 tsconfig.json 中。如果您使用的是沒有 TypeScript 的 Create React App,請改為將此儲存到 jsconfig.json 中。

tsconfig.json
{
"compilerOptions": {
"baseUrl": "src",
"paths": {
"test-utils": ["./utils/test-utils"]
}
}
}

Jest 28

如果您使用的是 Jest 28 或更高版本,現在必須單獨安裝 jest-environment-jsdom 套件。

npm install --save-dev jest-environment-jsdom

jsdom 也不再是預設環境。您可以透過編輯 jest.config.js 來全域啟用 jsdom

jest.config.js
 module.exports = {
+ testEnvironment: 'jsdom',
// ... other options ...
}

或者,如果您只需要在某些測試中使用 jsdom,您可以隨時使用docblocks 來啟用它

/**
* @jest-environment jsdom
*/

Jest 27

如果您使用的是最近版本的 Jest (27),jsdom 不再是預設環境。您可以透過編輯 jest.config.js 來全域啟用 jsdom

jest.config.js
 module.exports = {
+ testEnvironment: 'jest-environment-jsdom',
// ... other options ...
}

或者,如果您只需要在某些測試中使用 jsdom,您可以隨時使用docblocks 來啟用它

/**
* @jest-environment jsdom
*/

Jest 24 (或更低版本) 和預設值

如果您使用的是 Jest 測試框架版本 24 或更低版本,並且使用預設設定,建議使用 jest-environment-jsdom-fifteen 套件,因為 Jest 使用的 jsdom 環境版本缺少一些 React Testing Library 所需的功能和修正。

首先,安裝 jest-environment-jsdom-fifteen

npm install --save-dev jest-environment-jsdom-fifteen

然後指定 jest-environment-jsdom-fifteen 作為 testEnvironment

jest.config.js
 module.exports = {
+ testEnvironment: 'jest-environment-jsdom-fifteen',
// ... other options ...
}

在沒有 Jest 的情況下使用

如果您是在使用 webpack(或類似工具)捆綁的瀏覽器中執行測試,那麼 React 測試函式庫 應該可以直接使用。但是,大多數使用 React Testing Library 的人都是將其與 testEnvironment 設定為 jest-environment-jsdom 的 Jest 測試框架一起使用(這是 Jest 26 和更早版本的預設設定)。

jsdom 是 DOM 和瀏覽器 API 的純 JavaScript 實作,可在 Node 中執行。如果您未使用 Jest,並且想要在 Node 中執行測試,則必須自行安裝 jsdom。還有一個名為 global-jsdom 的套件,可用於設定全域環境以模擬瀏覽器 API。

首先,安裝 jsdomglobal-jsdom

npm install --save-dev jsdom global-jsdom

使用 mocha,測試命令看起來會像這樣

mocha --require global-jsdom/register

跳過自動清除

如果您使用的測試框架支援 afterEach 全域(例如 mocha、Jest 和 Jasmine),則預設會在每個測試後自動呼叫 Cleanup。但是,您可以選擇將 RTL_SKIP_AUTO_CLEANUP env 變數設定為 'true' 來跳過自動清除。您可以使用 cross-env 來執行此操作,如下所示

cross-env RTL_SKIP_AUTO_CLEANUP=true jest

為了讓這更容易,您也可以簡單地匯入 @testing-library/react/dont-cleanup-after-each,這將執行相同的操作。請確保在匯入 @testing-library/react 之前執行此操作。您可以使用 Jest 的 setupFiles 設定來執行此操作

{
// ... other jest config
setupFiles: ['@testing-library/react/dont-cleanup-after-each']
}

或使用 mocha 的 -r 標記

mocha --require @testing-library/react/dont-cleanup-after-each

或者,您可以在所有不想執行 cleanup 的測試中匯入 @testing-library/react/pure,並且不會自動設定 afterEach

Mocha 監看模式中的自動清除

在監看模式中使用 Mocha 時,全域註冊的清除只會在每個測試後第一次執行。因此,後續執行很可能會失敗,並出現TestingLibraryElementError:找到多個元素錯誤。

若要在 Mocha 的監看模式中啟用自動清除,請新增清除根掛鉤。建立一個包含以下內容的 mocha-watch-cleanup-after-each.js 檔案

mocha-watch-cleanup-after-each.js
const {cleanup} = require('@testing-library/react')

exports.mochaHooks = {
afterEach() {
cleanup()
},
}

並使用 mocha 的 -r 標記註冊它

mocha --require ./mocha-watch-cleanup-after-each.js