如何使用 React 测试库测试 Create-React-App(在 TypeScript 中)的特定元素
How to test specific elements of a Create-React-App (in TypeScript) with react testing library
我使用带有 --typescript 选项的 create-react-app 生成了一个项目。
这是我的应用程序:
import React from 'react';
const App: React.FC = () => {
return (
<div className="App">
<div>
<h1 id="pageHeader">Home page</h1>
<p>This is the Home page</p>
</div>
</div>
);
};
export default App;
我目前的测试是:
import React from 'react';
import ReactDOM from 'react-dom';
import {render} from '@testing-library/react';
import "@testing-library/jest-dom/extend-expect";
import App from './App';
test('Verify page header', () => {
const {getByText} = render(<App/>);
expect(getByText('Home page')).toBeInTheDocument;
});
问题:
我想再测试一下。除了测试“主页”是否出现在我页面的任何位置之外,我还想确保文本“主页”位于 h1 元素中。如何从 react-testing-library 获取完整元素(最好通过 getElementById)以便我可以使用 Jest 对其进行断言?
我是这样解决的:
test('Verify page header', () => {
const {container} = render(<App/>);
const pageHeaderElement = container.querySelector('#pageHeader');
if (pageHeaderElement) {
const pageHeaderElementContent = pageHeaderElement.firstChild;
if (pageHeaderElementContent) {
// You can either do:
expect(pageHeaderElementContent.textContent).toMatch('Home page');
// Or:
expect(pageHeaderElementContent).toMatchInlineSnapshot('Home page');
} else {
fail('Should have existed.');
}
} else {
fail('Should have existed.');
}
});
我在 react-testing 库的文档中发现了这个 toMatchInlineSnapshot 方法:
https://testing-library.com/docs/react-testing-library/api#render
带有新的 TypeScript 可选链接的较短版本:
test('Verify page header', () => {
const {container} = render(<App/>);
const pageHeaderContent = container.querySelector("#pageHeader")?.firstChild?.textContent;
expect(pageHeaderContent).toMatch('Home page');
});
几点,根据你自己的回答:
您应该避免在测试中出现任何逻辑分支。测试中的逻辑可能会导致不稳定的测试,因为测试中的逻辑没有经过测试。在您的情况下,if
块是不必要的,因为如果文本内容不存在,测试将已经失败。
有几种简单的方法可以测试文本 "Home Page" 是否在 h1
中:
查找文本并期望元素为 h1
:
test('Verify page header', () => {
const {getByText} = render(<App/>);
expect(getByText('Home page').tagName).toBe('H1');
});
或者给 h1
一个 data-testid
并使用 getByTestId
:
<h1 data-testid="pageHeader">Home Page</h1> // <-- In your component
test('Verify page header', () => {
const {getByTestId} = render(<App/>);
expect(getByTestId('pageHeader').textContent).toBe('Home Page');
});
我使用带有 --typescript 选项的 create-react-app 生成了一个项目。
这是我的应用程序:
import React from 'react';
const App: React.FC = () => {
return (
<div className="App">
<div>
<h1 id="pageHeader">Home page</h1>
<p>This is the Home page</p>
</div>
</div>
);
};
export default App;
我目前的测试是:
import React from 'react';
import ReactDOM from 'react-dom';
import {render} from '@testing-library/react';
import "@testing-library/jest-dom/extend-expect";
import App from './App';
test('Verify page header', () => {
const {getByText} = render(<App/>);
expect(getByText('Home page')).toBeInTheDocument;
});
问题: 我想再测试一下。除了测试“主页”是否出现在我页面的任何位置之外,我还想确保文本“主页”位于 h1 元素中。如何从 react-testing-library 获取完整元素(最好通过 getElementById)以便我可以使用 Jest 对其进行断言?
我是这样解决的:
test('Verify page header', () => {
const {container} = render(<App/>);
const pageHeaderElement = container.querySelector('#pageHeader');
if (pageHeaderElement) {
const pageHeaderElementContent = pageHeaderElement.firstChild;
if (pageHeaderElementContent) {
// You can either do:
expect(pageHeaderElementContent.textContent).toMatch('Home page');
// Or:
expect(pageHeaderElementContent).toMatchInlineSnapshot('Home page');
} else {
fail('Should have existed.');
}
} else {
fail('Should have existed.');
}
});
我在 react-testing 库的文档中发现了这个 toMatchInlineSnapshot 方法: https://testing-library.com/docs/react-testing-library/api#render
带有新的 TypeScript 可选链接的较短版本:
test('Verify page header', () => {
const {container} = render(<App/>);
const pageHeaderContent = container.querySelector("#pageHeader")?.firstChild?.textContent;
expect(pageHeaderContent).toMatch('Home page');
});
几点,根据你自己的回答:
您应该避免在测试中出现任何逻辑分支。测试中的逻辑可能会导致不稳定的测试,因为测试中的逻辑没有经过测试。在您的情况下,
if
块是不必要的,因为如果文本内容不存在,测试将已经失败。有几种简单的方法可以测试文本 "Home Page" 是否在
h1
中:
查找文本并期望元素为 h1
:
test('Verify page header', () => {
const {getByText} = render(<App/>);
expect(getByText('Home page').tagName).toBe('H1');
});
或者给 h1
一个 data-testid
并使用 getByTestId
:
<h1 data-testid="pageHeader">Home Page</h1> // <-- In your component
test('Verify page header', () => {
const {getByTestId} = render(<App/>);
expect(getByTestId('pageHeader').textContent).toBe('Home Page');
});