Введение
Enzyme — это инструмент тестирования React JavaScript с открытым исходным кодом от Airbnb, который упрощает экстраполяцию результатов работы компонентов React. API Enzyme является таким же гибким и простым в использовании, как манипулирование DOM с помощью jQuery, потому что он использует библиотеку cheerio для разбора виртуального DOM, а цель cheerio — выполнять jQuery на стороне сервера. Enzyme совместим с большинством библиотек утверждений и сред тестирования, таких как chai, mocha, jasmine и т. д.
установка и настройка
Перед использованием энзима необходимо установить зависимости энзима в проект, команда установки выглядит следующим образом:
npm install --save-dev enzyme
Поскольку проект React должен зависеть от некоторых вещей из React, убедитесь, что установлены следующие модули.
npm install --save react react-dom babel-preset-react
Для выполнения теста рендеринга помимо энзима также требуется поддержка библиотеки Enzyme Adapter, из-за разных версий React версии Enzyme Adapter тоже разные. Таблица соответствия между адаптерами и React выглядит следующим образом:
Enzyme Adapter Package | React semver compatibility |
---|---|
enzyme-adapter-react-16 | ^16.0.0 |
enzyme-adapter-react-15 | ^15.5.0 |
enzyme-adapter-react-14.4 | ^15.5.0 |
enzyme-adapter-react-14 | ^0.14.0 |
enzyme-adapter-react-13 | ^0.13.0 |
фермент поддерживает три способа рендеринга:shallow: поверхностный рендеринг, который является инкапсуляцией официального поверхностного рендерера. Рендеринг компонентов в виртуальные объекты DOM будет отображать только первый слой, а подкомпоненты не будут отображаться, поэтому эффективность очень высока. Среда DOM не требуется, и для доступа к информации о компонентах можно использовать jQuery;render: статическая визуализация, при которой компонент React преобразуется в статическую строку HTML, а затем используется библиотека Cheerio для анализа этой строки и возврата объекта экземпляра Cheerio, который можно использовать для анализа структуры HTML компонента.mount: полный рендеринг, при котором компонент визуализируется и загружается в реальный узел DOM, который используется для проверки взаимодействия DOM API и жизненного цикла компонента, а также использует jsdom для имитации среды браузера.
Общие функции
У фермента есть несколько основных функций, которые требуют внимания, а именно:
- симулировать (событие, макет): используется для имитации срабатывания события, событие — это имя события, макет — объект события;
- instance(): возвращает экземпляр тестового компонента;
- find(selector): Поиск узлов в соответствии с селектором.Селектор может быть селектором в CSS, конструктором компонента, отображаемым именем компонента и т. д.;
- at(index): возвращает визуализированный объект;
- get(index): возвращает реагирующий узел, чтобы протестировать его, его нужно перерендерить;
- содержит (nodeOrNodes): содержит ли текущий объект ключевой узел параметра, тип параметра — объект реакции или массив объектов;
- text(): возвращает текстовое содержимое текущего компонента;
- html(): возвращает форму HTML-кода текущего компонента;
- props(): возвращает все свойства корневого компонента;
- опоры (ключ): возвращает указанное свойство корневого компонента;
- state(): возвращает состояние корневого компонента;
- setState(nextState): установить состояние корневого компонента;
- setProps(nextProps): установить свойства корневого компонента;
использовать
Чтобы удобно объяснить использование теста Enzyme, мы сначала создадим новый тестовый файл фермента.js. код показывает, как показано ниже:
import React from 'react'
const Example=(props)=>{
return (<div>
<button>{props.text}</button>
</div>)
}
export default Example
Поверхностный рендеринг
Как упоминалось ранее, поверхностный рендеринг используется для рендеринга компонента в виртуальный объект DOM, но рендерится только первый слой, а не все дочерние компоненты, поэтому скорость обработки очень высока. И ему не нужна среда DOM, потому что он вообще не загружается в DOM.
Для неглубоких тестов поверхностного рендеринга мы создаем новый тестовый файл с именем фермент.test.js.
import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import Example from '../enzyme'
const {shallow}=Enzyme
Enzyme.configure({ adapter: new Adapter() })
describe('Enzyme shallow', function () {
it('Example component', function () {
const name='按钮名'
let app = shallow(<Example text={name} />)
let btnName=app.find('button').text();
console.log('button Name:'+btnName)
})
})
Выполните команду yarn test, и вы увидите следующие результаты:
Чтобы избежать написания каждого тестового файла таким образом, мы можем создать новый файл конфигурации энзим_config.test.js в тестовом каталоге. Содержимое файла следующее:
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({
adapter: new Adapter(),
});
export default Enzyme;
Затем создайте новый файл setup.js в тестовом каталоге:
import jsdom from 'jsdom';
const { JSDOM } = jsdom;
if (typeof document === 'undefined') {
const dom=new JSDOM('<!doctype html><html><head></head><body></body></html>');
global.window =dom.window;
global.document = global.window.document;
global.navigator = global.window.navigator;
}
Измените тестовый скрипт в нашем package.json на следующую конфигурацию:
"scripts": {
"test": "mocha --require babel-core/register --require ./test/setup.js"
}
Теперь наш неглубокий тестовый код можно изменить на:
import React from 'react'
import Enzyme from './enzyme.config';
import Example from '../enzyme'
const {shallow}=Enzyme
describe('Enzyme shallow', function () {
it('Example component', function () {
const name='按钮名'
let app = shallow(<Example text={name} />)
let btnName= app.find('button').text()
console.log('button Name:'+btnName)
})
})
полностью визуализировать крепление
рендеринг mount используется для загрузки компонентов React как реальных узлов DOM. Однако для реального DOM требуется среда браузера.Чтобы решить эту проблему, мы можем использовать jsdom, что означает, что мы можем использовать jsdom для имитации среды браузера для загрузки реальных узлов DOM. Сначала используйте следующую команду для установки jsdom для имитации среды браузера.Команда установки выглядит следующим образом:
npm install --save-dev jsdom
Затем мы добавляем полностью визуализированный тестовый код:
import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import Example from '../src/example'
const {shallow,mount}=Enzyme
Enzyme.configure({ adapter: new Adapter() })
describe('Enzyme mount的DOM渲染(Full DOM Rendering)中', function () {
it('Example组件中按钮的名字为子组件Sub中span的值', function () {
const name='按钮名'
let app = mount(<Example text={name} />)
const buttonObj=app.find('button')
const spanObj=app.find('span')
console.info(`查找到button的个数:${buttonObj.length}`)
console.info(`查找到span的个数:${spanObj.length}`)
buttonObj.text(),spanObj.text()
})
})
Обратите внимание, поскольку конфигурация завершения теста кажется немного проблематичной, код здесь может не работать.
статическая визуализация
Рендеринг статического рендеринга в основном используется для рендеринга компонента React в статическую строку HTML, а затем с помощью библиотеки Cheerio анализирует эту строку и возвращает объект экземпляра Cheerio, который можно использовать для анализа структуры HTML компонента. Для предыдущего файла фермента.js код для нашего теста статического рендеринга выглядит следующим образом:
import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import Example from '../enzyme'
const {shallow,mount,render}=Enzyme
Enzyme.configure({ adapter: new Adapter() })
describe('Enzyme render test', function () {
it('Example render', function () {
const name='按钮名'
let app = render(<Example text={name} />)
const buttonObj=app.find('button')
const spanObj=app.find('span')
console.info(`查找到button的个数:${buttonObj.length}`)
console.info(`查找到span的个数:${spanObj.length}`)
buttonObj.text(),spanObj.text()
})
})
Выполните приведенный выше код, результаты теста следующие:
В сравнении
Чтобы сравнить эти три тестовых фреймворка, мы можем сравнить их:
describe('shallow vs render vs mount', function () {
it('测试 shallow 500次', () => {
for (let i = 0; i < 500; i++) {
const app = shallow(<Example/>)
app.find('button').text()
}
})
it('测试render500次', () => {
for (let i = 0; i < 500; i++) {
const app = render(<Example/>)
app.find('button').text()
}
})
it('测试mount500次', () => {
for (let i = 0; i < 500; i++) {
const app = mount(<Example/>)
app.find('button').text()
}
})
})
Результат работы следующий:
Как показано выше, мелкий является самым быстрым, из-за ограничений мелкого рендеринга только первый слой, а не все дочерние компоненты. Получается, что рендер в два раза эффективнее монтирования. Итак, вопрос в том, какова ценность mount? Конечно, это ценно.Shallow и mount могут имитировать взаимодействие, потому что они оба являются объектами DOM.