Чтобы создавать надежные приложения React, вы должны иметь четкое представление о тестировании. В этой статье вы узнаете, как тестировать приложения React с помощью Jest, вы начнете свое первое базовое тестирование компонентов реакции, действий и редукторов.

Чему вы научитесь

  • Знакомство с шуткой
  • Это и ожидают функции
  • Введение в фермент
  • Тестовые редукторы
  • Тестирование создателей действий

Прежде чем мы начнем, как мы тестируем наше приложение:

  • Посмотрите на каждую отдельную часть вашего приложения.
  • Представьте, что вы говорите другу: «Вот что делает этот фрагмент кода».
  • Напишите тест, чтобы проверить, что делает каждая часть и что вы ожидаете.

Введение в Jest

Мы используем приложение create-реагировать для создания нового проекта. Проект поставляется с некоторыми зависимостями, а зависимости следующие:

  • Реагировать: Реагирующая библиотека
  • Babel: превращает ES2015 и jsx в код ES5.
  • Webpack: связать файлы javascript вместе
  • Jest: автоматический запуск тестов

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

Это работает

Каждый тестовый файл должен иметь функцию it, она используется для организации всех различных тестов, которые мы пишем внутри каждого отдельного файла, поэтому каждый раз, когда мы собираемся работать с тестовым файлом, мы будем вызывать это один раз.

Аргументы: первый — описание теста, второй — логика теста, которую мы собираемся выполнить.

it( "you test description" , () => {
// our test logic
})

Ожидать функцию

Функция ожидания используется каждый раз, когда вы хотите проверить значение. Каждая функция it содержит одно или несколько ожиданий.

ожидатьаргументы:

  • первый аргумент может быть объектом, массивом или свойством, которые мы пытаемся проверить.
  • оператор сопоставления второго аргумента, как мы хотим проверить предмет.
  • последний аргумент — это значение, которое мы ожидаем увидеть.
expect( // the value we want to inspect).( // matcher statement how we want to inspect the value ).( // value that we inpect to see )

Как мы используем фермент

Enzyme — это утилита для тестирования JavaScript для React, которая упрощает тестирование ваших компонентов React.

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

Давайте начнем наш первый тест

создайте реагирующее приложение и установите необходимые зависимости с помощью npm install.

npx create-react-app react-project
// then open the created project
npm install

Установки и настройки Enzyme

откройте свой терминал

npm i --save-dev enzyme enzyme-adapter-react-16

Перейдите в каталог src, откройте файл setupTests
src/setupTests.js
и импортируйте эти три строки

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });

Теперь ваш файл setupTests.js должен выглядеть так

Откройте каталог src и создайте новый компонент простой формы с содержимым простой текстовой формы.

import React from 'react'

const CommentsForm = () => {
    return (
        <div>
            Form Content
        </div>
    )
}
export default CommentsForm

Импортируйте его в компонент App.js

import React from "react";
import CommentsForm from "./CommentsForm";
function App() {
  return (
    <div className="App">
      <CommentsForm />
    </div>
  );
}
export default App;

Теперь давайте запустим наш первый тестовый компонент App.

Чтобы протестировать компонент App js, мы сначала создаем файл App.test.js рядом с файлом App.js, и jest будет искать все тестовые файлы в нашем приложении, но для более организованного способа есть еще один способ собрать ваши тестовые файлы в одной папке с именем с двойным underscore и заканчивался вот так __tests__ , и мы собираемся работать с ним таким образом

поэтому внутри вашего каталога src создайте новую папку с именем __tests__
внутри этой папки создайте App.js.test

import React from "react";
import { shallow } from "enzyme";
import App from "../App";
import CommentsForm from "../CommentsForm";
it("shows a comment form", () => {
const wrapped = shallow(<App />);
expect(wrapped.find(CommentsForm).length).toEqual(1);
});

Вот как выглядит тестовый файл для компонента приложения, давайте объясним его построчно
сначала мы импортируем реакцию, затем мы импортируем метод shallow из фермента, чтобы иметь экземпляр компонента приложения внутри наш тестовый файл, затем мы импортируем созданный нами компонент, чтобы проверить, есть ли у App.js дочерний компонент CommentsForm.js или нет.

После этого мы начинаем с функции it, как мы говорили ранее, она принимает первый аргумент описание нашего теста, затем у нас есть функция стрелки, которая содержит нашу тестовую логику.

constwrapped = small(‹App /›)Здесь мы берем экземпляр компонента App и визуализируем его.

Теперь посмотрите на аргументы функции ожидания.

  • первый обернутый нами аргумент, содержащий экземпляр компонента App.
  • оператор сопоставления второго аргумента, чтобы проверить, есть ли в нем компонент CommentsForm.
  • последний аргумент, мы ожидаем увидеть внутри него одну CommentsForm.

Теперь откройте свой терминал

npm run test
// this is the results
PASS  src/App.test.js
  ✓ shows a comment form (19ms)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.052s
Ran all test suites related to changed files.

Поздравляем! вы выполнили свой первый базовый тест для компонента приложения, и он пройден. если вы попытаетесь сделать последний аргумент для Equal(2), посмотрите на свой терминал, и вы обнаружите, что ваш тест FAIL, потому что он ожидал только один.

Тестирование избыточных действий и сокращений

Давайте установим Redux и создадим для него простой компонент, как мы сделали для компонента App.

npm install --save redux react-redux

Создайте новую папку reduxConfig в вашем каталоге src, чтобы обернуть все файлы redux, затем создайте папку действий и редукторы.

Действие
src/reduxConfig/actions/comments.js

import { SAVE_COMMENT } from "./types";
export function saveComment(comment) {
return {
type: SAVE_COMMENT,
payload: comment,
}
}

src/reduxConfig/actions/types.js

export const SAVE_COMMENT = 'SAVE_COMMENT';

Редуктор
src/reduxConfig/reducers/comments.js

import {SAVE_COMMENT} from '../actions/types';
export default function (state = [], action) {
switch (action.type) {
case SAVE_COMMENT:
// any time we see action with this type we add its payload to our state
return [...state,action.payload]
default:
return state;
}}

src/reduxConfig/редукторы/index.js

import { combineReducers } from "redux";
import commentsReducers from "./comments";
export default combineReducers({
comments: commentsReducers,
});

откройте index.js в вашем каталоге src, чтобы добавить провайдера и сохранить конфигурацию, как мы это делали раньше.

import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";
import { Provider } from "react-redux";
import { createStore } from "redux";
import * as serviceWorker from "./serviceWorker";
import reducers from "./redux config/reducers";
import "./index.css";
ReactDOM.render(
 <React.StrictMode>
  <Provider store={createStore(reducers,{})}>
   <App />
  </Provider>
 </React.StrictMode>,
document.getElementById("root")
);

Тестирование редуктора

src/reduxConfig/reducers/__tests__/comments.test.js

import { SAVE_COMMENT } from "../../actions/types";
import commentsList from "../comments";
it("handle action of type SAVE_COMMENT", () => {
const action = {  
type: SAVE_COMMENT,
payload: "new comment",
};
const newState = commentsList([], action);
expect(newState).toEqual(["new comment"]);
});

Вот наш первый тест для редуктора, давайте объясним его построчно

  1. Мы импортируем наш редьюсер, чтобы сделать на нем тест, и мы импортируем тип действия, после чего у нас есть функция it, содержащая нашу тестовую логику.
  2. Мы создаем поддельный создатель действия со значением полезной нагрузки.
  3. Мы оборачиваем импортированный редюсер и наш создатель поддельного действия, чтобы проверить, что значение полезной нагрузки действия будет добавлено в наш редюсер.
npm run test
// this is the results
PASS src/App.test.js
 PASS src/reduxConfig/reducers/__tests__/comments.test.js
Test Suites: 2 passed, 2 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 2.447s
Ran all test suites related to changed files.

Создатели тестовых действий

src/reduxConfig/actions/__tests__/comments.test.js

import { saveComment } from "../comments";
import { SAVE_COMMENT } from "../types";
it("has the correct type", () => {
const action = saveComment();
expect(action.type).toEqual(SAVE_COMMENT);
});
it("has the correct payload", () => {
const action = saveComment("new comment");
expect(action.payload).toEqual("new comment");
});

Вот наш первый тест на действие, давайте объясним его построчно

  1. Мы импортируем нашего создателя действия и импортируем тип действия, затем у нас есть две функции it, содержащие нашу тестовую логику.
  2. Во-первых, это функциональная проверка, имеет ли создатель действия правильный тип, поэтому, если вы укажете неправильный тип, тестирование может помочь нам избежать и исправить эти небольшие ошибки.
  3. Во-вторых, это функция тестирования нашего создателя действий, которая проверяет, когда мы передаем ему комментарий, который должен быть назначен полезной нагрузке.
npm run test
// this is the results
 PASS  src/reduxConfig/reducers/__tests__/comments.test.js
 PASS  src/App.test.js
 PASS  src/reduxConfig/actions/__test__/comments.test.js
Test Suites: 3 passed, 3 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        3.005s
Ran all test suites related to changed files.

Вот репозиторий gethup этого проекта

Ссылка

Вот и все!. Надеюсь, это помогло вам 🙂