Введение: - Этот блог посвящен тестированию компонента React с помощью Enzyme и Jest. В этом блоге мы обсуждаем, как тестировать реагирующие компоненты, которые имеют контент d3, с помощью Enzyme и Jest. Этот блог поможет вам написать тестовые примеры, а также поможет вам выбрать правильную среду тестирования в соответствии с вашими требованиями.

В этом блоге я расскажу о некоторых фреймворках для тестирования, которые показаны ниже.

  1. Шутка
  2. Жасмин
  3. Фермент

Шутка

Jest - это тестовая среда с открытым исходным кодом, созданная Facebook, которая отлично интегрируется с React.js. Это очень мощный фреймворк для тестирования. Самая известная особенность шутки - снимок. Это очень полезно для тестирования.

Особенности Jest: -

  1. Нулевая конфигурация
  2. Быстро и в песочнице
  3. Расширяемый фреймворк
  4. Codemods
  5. Снимок

Чтобы узнать больше, перейдите по указанной ниже ссылке: -

Https://jestjs.io/docs/en/getting-started

Жасмин

Jasmine - одна из популярных сред модульного тестирования JavaScript, способная тестировать синхронный и асинхронный код JavaScript. Он используется в программировании BDD (поведенческая разработка), в котором больше внимания уделяется бизнес-ценности, чем техническим деталям.

Особенности жасмина: -

  1. Jasmine не зависит от других фреймворков JavaScript.
  2. Jasmine не требует DOM.
  3. Весь синтаксис, используемый во фреймворке Jasmine, ясен и очевиден.
  4. На Jasmine сильно повлияли Rspec, JS Spec и Jspec.
  5. 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’);
});
});

Функции до и после: - Жасмин поддерживает несколько функций до и после.

  1. BeforeAll
  2. ДоКаждый
  3. После всего
  4. 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.

Перед установкой фермента сохраните следующие ключевые моменты.

  1. Если вы используете react 16.X, вам необходимо установить фермент-адаптер-react-16 и фермент 3.X
  2. Если вы используете 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, некоторые из важных вопросов, о которых я здесь рассказываю.

  1. Основная проблема заключается в том, что содержимое d3 не отображается с помощью Enzyme.
  2. Найдите содержимое d3 с помощью .html (), теперь проблема, как манипулировать этим html ().
  3. Переход используется в d3.
  4. Как выполнить событие клика
  5. Как вызвать методы жизненного цикла 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”);
 });
 });
});