Введение: - Этот блог посвящен тестированию компонента React с помощью Enzyme и Jest. В этом блоге мы обсуждаем, как тестировать реагирующие компоненты, которые имеют контент d3, с помощью Enzyme и Jest. Этот блог поможет вам написать тестовые примеры, а также поможет вам выбрать правильную среду тестирования в соответствии с вашими требованиями.
В этом блоге я расскажу о некоторых фреймворках для тестирования, которые показаны ниже.
- Шутка
- Жасмин
- Фермент
Шутка
Jest - это тестовая среда с открытым исходным кодом, созданная Facebook, которая отлично интегрируется с React.js. Это очень мощный фреймворк для тестирования. Самая известная особенность шутки - снимок. Это очень полезно для тестирования.
Особенности Jest: -
- Нулевая конфигурация
- Быстро и в песочнице
- Расширяемый фреймворк
- Codemods
- Снимок
Чтобы узнать больше, перейдите по указанной ниже ссылке: -
Https://jestjs.io/docs/en/getting-started
Жасмин
Jasmine - одна из популярных сред модульного тестирования JavaScript, способная тестировать синхронный и асинхронный код JavaScript. Он используется в программировании BDD (поведенческая разработка), в котором больше внимания уделяется бизнес-ценности, чем техническим деталям.
Особенности жасмина: -
- Jasmine не зависит от других фреймворков JavaScript.
- Jasmine не требует DOM.
- Весь синтаксис, используемый во фреймворке Jasmine, ясен и очевиден.
- На Jasmine сильно повлияли Rspec, JS Spec и Jspec.
- Jasmine - это фреймворк с открытым исходным кодом, который легко доступен в различных версиях, таких как автономный, ruby gem, Node.js и т. Д.
Suite Block: - Jasmine - это фреймворк для тестирования JavaScript. Пакет - это базовый строительный блок фреймворка Jasmine. Набор тестовых примеров аналогичного типа, написанных для определенного файла или функции, известен как один набор. Он содержит два других блока: один - «Описать ()», а другой - «Оно ()».
Один блок Suite может иметь только два параметра: один «имя этого набора» и другой «Объявление функции», который фактически вызывает функциональность нашего модуля, которая должна быть протестирована. .
Пример:-
describe(“Hello World”, function () { it(“should Return Hello world”, function () { expect(HelloWorld()).toEqual(‘Hello World’); }); });
Пропустить блок: - Jasmine также позволяет разработчикам пропустить один или несколько тестовых случаев. Эти методы могут применяться на уровне спецификации или уровне набора. В зависимости от уровня приложения этот блок может называться Skipping Spec и Skipping Suite соответственно. Мы пропустим конкретный Spec или Suite, используя символ «x».
Пример:-
describe(“Hello World”, function () { xit(“should Return Hello world”, function () { expect(HelloWorld()).toEqual(‘Hello World’); }); });
Функции до и после: - Жасмин поддерживает несколько функций до и после.
- BeforeAll
- ДоКаждый
- После всего
- AfterEach
BeforeAll: - запускает функцию перед запуском любого из тестов в этом файле. Если функция возвращает обещание или является генератором, Jest ожидает выполнения этого обещания перед запуском тестов.
При желании вы можете указать тайм-аут (в миллисекундах), чтобы указать, как долго ждать перед прерыванием. Примечание. Тайм-аут по умолчанию составляет 5 секунд.
Пример: -
beforeAll((done) => { document.body.appendChild(element); barGraph = ReactDOM.render( <BarGraph configuration={config.verticalNumber} data={config.data} />, element ) setTimeout(() => { done(); }, 1000); });
BeforeEach: - запускает функцию перед запуском каждого из тестов в этом файле. Если функция возвращает обещание или является генератором, Jest ожидает выполнения этого обещания перед запуском теста.
При желании вы можете указать тайм-аут (в миллисекундах), чтобы указать, как долго ждать перед прерыванием.
Пример: -
beforeEach( async () => { if(global.ZFB_DOWNLOAD_INSTANCE) { await clickByIdAfterWait(global.ZFB_DOWNLOAD_INSTANCE); } });
AfterAll: - запускает функцию после завершения всех тестов в этом файле. Если функция возвращает обещание или является генератором, Jest ожидает выполнения этого обещания, прежде чем продолжить.
При желании вы можете указать тайм-аут (в миллисекундах), чтобы указать, как долго ждать перед прерыванием.
Пример: -
afterAll(‘do logout’, async () => { await clickByIdAfterWait(‘logout’); });
AfterEach: - запускает функцию после завершения каждого из тестов в этом файле. Если функция возвращает обещание или является генератором, Jest ожидает выполнения этого обещания, прежде чем продолжить.
При желании вы можете указать тайм-аут (в миллисекундах), чтобы указать, как долго ждать перед прерыванием.
Пример: -
afterEach( async () => { await wait(300); await clickByIdAfterWait(‘editor-button-policygroups’); await wait(300); await selectEntities(vportPG, entity, [global.PG_INSTANCE_ID_2]); });
Шпионы: - Jasmine spy - это еще одна функция, которая выполняет то же самое, что указано в ее названии. Это позволит вам следить за вызовами функций вашего приложения. В Jasmine доступны два типа шпионских технологий. Первая методология может быть реализована с помощью spyOn (), а вторая методология может быть реализована с помощью createSpy ().
Пример: -
spyOn(self.mockService, ‘fetch’).and.callThrough(); VSDServiceTest.makeRequest = jasmine.createSpy(“makeRequest”).and.callFake(() => { return new Promise((resolve, reject) => { return resolve(‘Done’); }) });
Фермент
Фермент - это утилита для тестирования JavaScript для React, которая упрощает утверждение, управление и просмотр выходных данных компонентов React.
API Enzyme должен быть интуитивно понятным и гибким, имитируя API jQuery для управления и обхода DOM.
Перед установкой фермента сохраните следующие ключевые моменты.
- Если вы используете react 16.X, вам необходимо установить фермент-адаптер-react-16 и фермент 3.X
- Если вы используете react 15.X, вам необходимо установить фермент-адаптер-react-15 и фермент 2.X
URL: - https://airbnb.io/enzyme/docs/installation/
Запуск энзимных тестов: - У Enzyme нет единого мнения относительно того, какую программу запуска тестов или библиотеку утверждений вы используете, и она должна быть совместима со всеми основными программами выполнения тестов и библиотеками утверждений. В документации и примерах для ферментов используются мокко и чай, но вы должны иметь возможность экстраполировать их на выбранную вами структуру. Если вы заинтересованы в использовании фермента с настраиваемыми утверждениями и удобными функциями для тестирования компонентов React, вы можете рассмотреть возможность использования:
Это некоторый обзор среды тестирования. Теперь время для основной темы.
Тестирование React и содержания D3 с помощью фермента
Очень сложно протестировать содержимое d3 с помощью react, потому что фермент или любая другая среда тестирования визуализирует только метод рендеринга React. Когда искал решение этой проблемы. Я читал многие документы, некоторые из которых поддерживают тестирование d3 с жасмином без React, а некоторые документы предназначены для шуток и с ферментом для тестирования компонентов React. Для одновременного тестирования реакции и d3 я нашел один подход. Я визуализировал dom с помощью фермента, но при визуализации фермента я не могу получить содержимое d3. Чтобы получить содержимое d3, я использовал метод .html (), который предоставляет HTML-код текущего компонента. Я нашел HTML, но теперь вопрос в том, как манипулировать HTML и как тестировать содержимое как d3, так и React. После долгих поисков я нашел одну управляющую библиотеку - Cheerio. Это похоже на библиотеку jquery. С его помощью я могу вместе тестировать d3 и React. Это краткое изложение того, как я тестирую React и d3 вместе. Сейчас я подробно расскажу, как у меня все работает.
Проблемы: - Тестировать React и d3 вместе очень сложно. Я столкнулся со многими проблемами при совместном тестировании d3 и React, некоторые из важных вопросов, о которых я здесь рассказываю.
- Основная проблема заключается в том, что содержимое d3 не отображается с помощью Enzyme.
- Найдите содержимое d3 с помощью .html (), теперь проблема, как манипулировать этим html ().
- Переход используется в d3.
- Как выполнить событие клика
- Как вызвать методы жизненного цикла React.
Это некоторые серьезные проблемы, с которыми я столкнулся, когда тестировал реакцию и d3 вместе с энзимом и шуткой.
Решения
- Основная проблема заключается в том, что контент d3 не обрабатывается с помощью Enzyme.
Решение: - Для рендеринга контента я использую метод крепления Enzyme. Mount используется для полного рендеринга dom. В моем случае есть одна проблема, которая связана с содержимым d3, потому что мы используем содержимое d3 с содержимым реакции. Я использую Enzyme mount с помощью метода mount (). Я могу получить компонент React, но я не могу получить содержимое d3, потому что содержимое d3 монтируется с рендером после завершения установки реакции. После долгих поисков я нашел одно решение этой проблемы. Сначала у меня есть HTML-код смонтированного дома, и я могу получить полный HTML-код.
Пример : -
import PieGraph from ‘./index’; import React from ‘react’; import { mount } from ‘enzyme’; describe(“PieGrpah”, () => { let config; beforeAll(async () => { config = await getDataAndConfig(‘PieGraph’); }); it(“OtherOption by Number”, () => { const pieGraph = mount( <PieGraph width={500} height={500} configuration={config.withoutOtherOption} data={config.data}> </PieGraph> ); const html = pieGraph.find(‘svg’).html(); }); });
С помощью метода .html () я могу получить содержимое d3, но теперь у меня есть другая проблема, показанная ниже.
- Найдите содержимое d3 с помощью .html (). Теперь проблема в том, как манипулировать этим HTML.
Решение: - Теперь проблема в том, как манипулировать компонентом HTML, чтобы решить проблему. Я нашел одну библиотеку, которая называется Cheerio. Cheerio используется для управления данными HTML. Cheerio в основном используется для управления содержимым HTML. Он предоставляет множество интересных методов. Cheerio анализирует разметку и предоставляет API для просмотра / управления полученной структурой данных.
Чтобы узнать больше о Cheerio, перейдите по ссылке ниже.
Https://www.npmjs.com/package/cheerio
Пример:-
pieGraph.test.js import PieGraph from ‘./index’; import React from ‘react’; import { mount } from ‘enzyme’; import { getDataAndConfig, getHtml, checkSvg } from ‘./helper’; describe(“PieGrpah”, () => { let config; beforeAll(async () => { config = await getDataAndConfig(‘PieGraph’); }); describe(“OtherOption by Percentage”, () => { let pieGraph, $; beforeAll(async () => { pieGraph = mount( <PieGraph width={500} height={500} configuration={config.percentage} data={config.data}> </PieGraph> ); $ = getHtml(pieGraph, ‘svg’); }); it(“SVG Dimensions”, () => { const result = checkSvg(pieGraph); expect(result).toBeTruthy(); }); }); }); Helper.js const cheerio = require(‘cheerio’); export const checkSvg = (component) => { const $ = getHtml(component, ‘svg’); const svgHeight = $(‘svg’).attr(‘height’); const svgWidth = $(‘svg’).attr(‘width’); return svgHeight == “500” && svgWidth == “500”; } export const getHtml = (component, tag) => { const cheerioData = cheerio.load(component.find(tag).html()); return cheerioData; }
С помощью Cheerio я смог протестировать большую часть графика, а также смог охватить большинство случаев, но когда я тестировал гистограмму, я не смог получить HTML. После долгого рытья я смог понять, в чем проблема. Проблема упоминается ниже.
- Переход используется в d3.
Решение. - В некоторых случаях для анимации использовался переход d3. Теперь проблема заключалась в том, что контент d3 не был готов во время монтирования компонента. Таким образом, содержимое d3 недоступно в HTML. Это большая проблема для решения этой проблемы. Я использовал setTimeout. В разделе тайм-аута я обновил компонент. После обновления компонента я смог решить эту проблему. Я могу получить контент d3.
Пример: -
barGraph.test.js import BarGraph from ‘./index’; import React from ‘react’; import { mount } from ‘enzyme’; import { getDataAndConfig, getHtml, checkSvg } from ‘./helper’; describe(“Bar Graph”, () => { let config; beforeAll(async () => { config = await getDataAndConfig(‘DynamicBarGraph’); }); describe(“Graph with Brush”, () => { let horizontalBrush, $; beforeAll(async (done) => { horizontalBrush = mount( <BarGraph width={500} height={500} configuration={config.horizontalBrush} data={config.data}> </BarGraph> ); /* Delayed added because the bar is rendered with 300ms animation */ setTimeout(() => { horizontalBrush.update(); done(); }, 350); }); it(“SVG Dimensions”, () => { const result = checkSvg(horizontalBrush); expect(result).toBeTruthy(); }); }); }); Helper.js const cheerio = require(‘cheerio’); export const checkSvg = (component) => { const $ = getHtml(component, ‘svg’); const svgHeight = $(‘svg’).attr(‘height’); const svgWidth = $(‘svg’).attr(‘width’); return svgHeight == “500” && svgWidth == “500”; } export const getHtml = (component, tag) => { const cheerioData = cheerio.load(component.find(tag).html()); return cheerioData; }
- Как выполнить событие клика.
Решение: - Эта является для меня самой сложной проблемой, потому что с помощью cheerio я могу манипулировать HTML, но cheerio не имеет функции события щелчка. Это блокиратор для меня без этого тестирование неполное. Я много искал, потом нашел решение. Чтобы проверить clickEvent, я использовал рендеринг react-dom. С помощью отрисовки react-dom я могу протестировать событие щелчка. Я также использовал для этого функцию jest mock.
Пример:-
import React from ‘react’; import { mount } from ‘enzyme’; import ReactDOM from ‘react-dom’; import PieGraph from ‘.’; describe(“PieGrpah”, () => { let config; beforeAll(async () => { config = await getDataAndConfig(‘PieGraph’); }); describe(“Click Event”, () => { let pieGraph; const mockCallBack = jest.fn(); const element = document.createElement(“div”); beforeAll((done) => { document.body.appendChild(element); pieGraph = ReactDOM.render( <PieGraph width={500} height={500} configuration={config.withoutOtherOption} data={config.data} onMarkClick={mockCallBack} />, element ) setTimeout(() => { done(); }, 1000); }); afterAll(() => { document.body.removeChild(element); }); it(“Click On PieGraph”, () => { element.querySelector(‘path’).click(); expect(mockCallBack).toHaveBeenCalled(); }); }); });
- Как вызвать методы жизненного цикла React.
Решение: - все мы уже знаем, что в React есть некоторые методы жизненного цикла. Все методы жизненного цикла обладают уникальной функциональностью и временем выполнения. Некоторые вызываются после монтажа, а некоторые вызываются перед монтажом. На графике датчика к игле применяется анимация. Вся работа выполняется в методе componentDidmount. Очень сложно найти угол иглы и процентное соотношение, потому что и то, и другое выполняется в методе componentDidmount. После долгих поисков я нашел одно решение. Я тестировал эту штуку с помощью react-dom-render. С помощью этого я могу получить весь контент, такой как угол и процент иглы.
Пример:-
import React from ‘react’; import ReactDOM from ‘react-dom’; import { getDataAndConfig } from ‘../testHelper’; import GaugeGraph from ‘.’; const cheerio = require(‘cheerio’); describe(“GaugeGraph”, () => { let config; beforeAll(async () => { config = await getDataAndConfig(‘GaugeGraph’); }); describe(“Initial Configurations”, () => { let gaugeGraph, $; const element = document.createElement(“div”); beforeAll((done) => { document.body.appendChild(element); gaugeGraph = ReactDOM.render( <GaugeGraph width={500} height={500} configuration={config.configuration} data={config.data} />, element ) setTimeout(() => { done(); $ = cheerio.load(element.innerHTML); }, 3000); }); afterAll(() => { document.body.removeChild(element); }); it(“SVG Dimensions”, () => { const height = $(‘svg’).attr(‘height’); const width = $(‘svg’).attr(‘width’); expect(height).toEqual(“500”); expect(width).toEqual(“500”); }); }); });