Close

14 июня, 2021

React, TypeScript и TDD

Почему разработка через тестирование?

Разработка через тестирование, или TDD, позиционируется как способ выполнить дополнительную работу заранее, чтобы улучшить качество и сэкономить время в будущем. Большинство людей, когда об этом говорят, слышат: «Бла-бла, дополнительная работа, бла-бла-бла» и пропускают все мимо ушей.

В этой серии руководств мы попытаемся представить «сначала тесты» в ином свете: это быстрее и веселее. Почему быстрее? Я пишу компонент React и хочу посмотреть, работает ли он. Я выхожу из редактора, захожу в браузер, перехожу на сайт и надеюсь, что не сломал что-то в маршруте или представлении. Используя стиль разработки, описанный в этой статье, вы остаетесь в своем интеллектуальном редакторе, в нескольких строках тестового кода и наблюдаете, как все постепенно начинает работать.

И даже не заставляйте меня начинать отладку во время разработки компонентов, иначе говоря console.log. Вместо этого вы сидите в своем тесте под NodeJS и устанавливаете точки прерывания.

Счастье? В тестировании.

Это серьезное заявление. Но это правда. Вместо того, чтобы прерывать ваш мысленный «поток» между инструментами и контекстами, вы остаетесь в своей IDE, где у вас есть мышечная память поверх ментальной памяти. Код слева, тест справа, тестовый вывод внизу.

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

Напутать что-то? Благодаря TypeScript вы быстрее справитесь с неработающим тестом. Если вы сломали что-то, что не является URL-адресом, который перезагружается приложением create-response-app, вы тоже об этом узнаете. Это ощущение спокойного, методичного прогресса.

Настройка

Я не буду вдаваться в подробности того, как приступить к работе: они находится на этапе обучения и хорошо знакомы всем, кто использовал приложение Create React. Тем не менее, чтобы сориентироваться, я покажу несколько вещей.

Что такое Create ReactApp (CRA)? Modern React, как и все остальное в веб-разработке, стал ужасно неудобным. CRA — это платформа для создания новых проектов React с использованием известного набора рабочих пакетов.

Вы можете самостоятельно освоить сотни пакетов и конфигурации npm и поддерживать их в актуальном состоянии по мере изменения ситуации. CRA не только создает для вас рабочий проект, но и перемещает текущую конфигурацию в свой пакет. Это означает, что они будут продолжать работать.

Создать новый проект с помощью npx (команда npm для получения и запуска пакета) очень просто:

JavaScript
$ npx create-react-app my-app —template typescript

1 $ npx create-react-app my-app —template typescript

Современные IDE, вероятно, автоматизируют это за вас как часть мастера New Project. Затем npx получит пакет create-response-app, запустит его и передаст аргумент шаблона, говорящий о создании пакета, использующего TypeScript. Вы, вероятно, будете смеяться над этим самоуверенным сообщением журнала:

JavaScript
Installing packages. This might take a couple of minutes.

1 Installing packages. This might take a couple of minutes.

Команда также инициализирует репозиторий git, создает package.json и выполняет эквивалент npm install для созданного вами пакета. На момент написания этой статьи в каталоге node_modules было всего 1063 записи. Спасибо CRA, за то, что управляет всем этим.

Теперь у вас есть рабочий Hello World на React и TypeScript. Чтобы увидеть его в действии, запустите:

JavaScript
$ npm start

1 $ npm start

В вашей IDE, вероятно, есть способ запустить это с помощью клика мышью. Например, в WebStorm и других IDE IntelliJ:

React, TypeScript и TDD

Вы увидите несколько сообщений журнала при запуске сервера разработки, и браузер откроется по адресу http://localhost:3000 — удобно! Откуда «начало»? Взгляните на блок «scripts» в сгенерированном файле package.json:

JavaScript
«start»: «react-scripts start»,

1 «start»: «react-scripts start»,

Это ярлык для консольного скрипта, предоставленного CRA.

Но подождите, это еще не все! Пока сервер разработки все еще работает, откройте файл src/App.tsx и добавьте текст <p>, затем сохраните. Через секунду или две ваш браузер покажет обновление. CRA следит за изменениями, прозрачно выполняет четыре триллиона инструкций по изменению кода внешнего интерфейса и выполняет интеллектуальную перезагрузку с помощью браузера.

Если вы посмотрите на package.json, то увидите, что он довольно компактен.

JavaScript
{
«name»: «react_ts_tdd»,
«version»: «0.1.0»,
«private»: true,
«dependencies»: {
«@testing-library/jest-dom»: «^5.11.4»,
«@testing-library/react»: «^11.1.0»,
«@testing-library/user-event»: «^12.1.10»,
«@types/jest»: «^26.0.15»,
«@types/node»: «^12.0.0»,
«@types/react»: «^17.0.0»,
«@types/react-dom»: «^17.0.0»,
«react»: «^17.0.2»,
«react-dom»: «^17.0.2»,
«react-scripts»: «4.0.3»,
«typescript»: «^4.1.2»,
«web-vitals»: «^1.0.1»
},
«scripts»: {
«start»: «react-scripts start»,
«build»: «react-scripts build»,
«test»: «react-scripts test»,
«eject»: «react-scripts eject»
},
«eslintConfig»: {
«extends»: [
«react-app»,
«react-app/jest»
]
},
«browserslist»: {
«production»: [
«>0.2%»,
«not dead»,
«not op_mini all»
],
«development»: [
«last 1 chrome version»,
«last 1 firefox version»,
«last 1 safari version»
]
}
}

12345678910111213141516171819202122232425262728293031323334353637383940414243 {  «name»: «react_ts_tdd»,  «version»: «0.1.0»,  «private»: true,  «dependencies»: {    «@testing-library/jest-dom»: «^5.11.4»,    «@testing-library/react»: «^11.1.0»,    «@testing-library/user-event»: «^12.1.10»,    «@types/jest»: «^26.0.15»,    «@types/node»: «^12.0.0»,    «@types/react»: «^17.0.0»,    «@types/react-dom»: «^17.0.0»,    «react»: «^17.0.2»,    «react-dom»: «^17.0.2»,    «react-scripts»: «4.0.3»,    «typescript»: «^4.1.2»,    «web-vitals»: «^1.0.1»  },  «scripts»: {    «start»: «react-scripts start»,    «build»: «react-scripts build»,    «test»: «react-scripts test»,    «eject»: «react-scripts eject»  },  «eslintConfig»: {    «extends»: [      «react-app»,      «react-app/jest»    ]  },  «browserslist»: {    «production»: [      «>0.2%»,      «not dead»,      «not op_mini all»    ],    «development»: [      «last 1 chrome version»,      «last 1 firefox version»,      «last 1 safari version»    ]  }}

Что ж, «компактно» относительно объема выполняемой работы. Гениальность приложения create-react-app заключается в том, чтобы переместить кучу файлов конфигурации в свои пакеты. Таким образом, они управляют этими решениями и всей сложностью. Затем вы можете обновить эти пакеты и получить новую / фиксированную связку всех инструментов сборки JavaScript.

Запустим еще один из скриптов, предоставленных CRA:

JavaScript
$ npm run-script build

1 $ npm run-script build

Это займет некоторое время, так как он гипероптимизирует сгенерированный сайт / приложение React в каталоге build. Затем его можно развернуть на сервере.

Привет, тест

«Вы меня взволновали тестированием, а не тестированием, а где тестирование!» Вы правы! Давайте проведем небольшое тестирование, следуя этому руководству.

Во-первых, немного предыстории. Знаю, знаю, скоро пройду тест. CRA самодостаточен. Он выбирает важные пакеты, генерирует конфигурацию и поддерживает работу установки. Для тестировани CRA использует три важных инструмента:

Фреймворк тестирования Jest

jsdom как смоделированный браузер

React-testing-library как библиотеку утверждений

Достаточно церемонии. Запустим тесты:

JavaScript
$ npm run-script test

1 $ npm run-script test

Вы получите сообщение, что у CRA нет тестов, которые изменились на основе Git:

React, TypeScript и TDD

Откройте src/app/App.tsx и измените save to reload на save to reload!!. Вы увидите, что результат выглядит примерно так:

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

React, TypeScript и TDD

У наблюдателя есть несколько вариантов ограничения того, что он ищет, что действительно помогает продуктивности. На этот раз замените «Learn React» в src/App.tsx на «Master React». Наблюдатель повторно запускает тесты, которые теперь не работают:

React, TypeScript и TDD

В среде IDE вы можете взглянуть на это более подробно. Например, вот как выглядит результат провального теста в WebStorm:

React, TypeScript и TDD

Что здесь на самом деле происходит? Что исполняется? Как упоминалось ранее, CRA использует Jest для выполнения теста. Это делает Jest … подождите … тест- раннер. Он предоставляет конфигурацию, командные флаги (например, наблюдатель), способы поиска тестов и т. Д. Он также связывает jsdom в качестве предварительно настроенной тестовой среды , что далеко от слова «браузер».

jsdom действительно хорош. Это поддельный браузер, написанный на JS, который работает на NodeJS и делает вид, что отображает вашу разметку и выполняет ваш JavaScript. Это сверхбыстрая ненавязчивая альтернатива запуску Chrome для каждого теста.

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

На что это похоже? Как выглядит настоящий тест? Вот тест, который Create React App генерирует по умолчанию:

JavaScript
import React from ‘react’;
import { render, screen } from ‘@testing-library/react’;
import App from ‘./App’;

test(‘renders learn react link’, () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

123456789 import React from ‘react’;import { render, screen } from ‘@testing-library/react’;import App from ‘./App’; test(‘renders learn react link’, () => {  render(<App />);  const linkElement = screen.getByText(/learn react/i);  expect(linkElement).toBeInTheDocument();});

Мы увидим больше ниже, когда действительно перейдем к TDD. Но пока … это хороший способ работы: оставаться в редакторе и быстрее находить проблемы в коде.

Отладка во время тестирования с помощью NodeJS

Мы уже многое показали, достаточно для того, чтобы — по крайней мере, для меня — убедить работать по принципу «сначала тестирование». Но есть еще одна часть, которая явно превосходит альтернативу: отладка. Это описано в тексте и видео в пошаговом руководстве в этом разделе. Тут показана интеграция с конкретным инструментом (WebStorm), но концепции применимы и в других местах.

Представьте, что вместо простого <h1> с label нам нужна функция, которая формулирует «приветствие». Эта функция может принимать аргумент для имени, с которым можно поздороваться, и мы хотим записать это имя в верхний регистр.

Мы могли бы написать функцию и вставить вызов в заголовок. Но давайте сначала напишем тест:

JavaScript
test(‘generates a label’, () => {
const result = label(«React»);
expect(result).toEqual(«Hello REACT»);
});

1234 test(‘generates a label’, () => {  const result = label(«React»);  expect(result).toEqual(«Hello REACT»);});

Тест не пройден: мы не написали функцию формирования label. Фактически, наш инструмент предупредил нас, что мы его даже не импортировали:

React, TypeScript и TDD

Теперь напишем функцию формирования label:

JavaScript
export function label(name) {
return `Hello ${name.toUpperCase()}`;
}

123 export function label(name) {    return `Hello ${name.toUpperCase()}`;}

Как только мы ее импортируем в src/App.test.tsx, тесты начнут проходить. Это здорово, но если мы передадим функции целое число вместо строки:

JavaScript
test(‘generates a label’, () => {
const result = label(42);
expect(result).toEqual(«Hello REACT»);
});

1234 test(‘generates a label’, () => {  const result = label(42);  expect(result).toEqual(«Hello REACT»);});

… тест рассердится:

React, TypeScript и TDD

Допустим, мы не можем легко решить проблему. Вместо того, чтобы разбрызгивать console.log повсюду, мы можем использовать … отладчик! Установите точку останова на строке в тесте:

React, TypeScript и TDD

Теперь запустим тесты, но под отладчиком:

React, TypeScript и TDD

Выполнение остановится на этой строке в тесте. Вы можете выбрать «Шаг с заходом», чтобы перейти к функции label, а затем в интерактивном режиме перемещаться по ней. Затем вы обнаружите — у целых чисел нет метода toUpperCase:

React, TypeScript и TDD

Фактически, TypeScript предупреждал нас об этом:

React, TypeScript и TDD

Чтобы защититься от этого в будущем, добавьте информацию о типе в аргумент имени функции label:

JavaScript
export function label(name: string) {
return `Hello ${name.toUpperCase()}`;
}

123 export function label(name: string) {    return `Hello ${name.toUpperCase()}`;}

Отладка во время написания теста — и оставаясь в NodeJS, то есть в вашем инструменте — очень продуктивна. Это намного продуктивнее, чем вселенная console.log или использование отладчика браузера.

Заключение

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

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

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

Автор: Paul Everitt

Источник: webformyself.com

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Яндекс.Метрика
Открыть чат
Если есть вопросы пишите нам
Здравствуйте.
Чем вам помочь?