React, TypeScript и TDD

React, TypeScript и TDD

От автора: ReactJS очень популярен и поэтому широко поддерживается. TypeScript становится все более популярным и поэтому все более широко поддерживается. А если они вместе? Становится намного лучше. Они оба в контексте разработки через тестирование в сочетании с интеллектуальными инструментами?

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

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

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

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

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

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

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

Настройка

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

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

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

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

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

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

Installing packages. This might take a couple of minutes.

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

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

$ npm start

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

React, TypeScript и TDD

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

"start": "react-scripts start",

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

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

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

{ "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:

$ npm run-script build

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

Привет, тест

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

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

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

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

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

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

$ npm run-script test

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

React, TypeScript и TDD

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

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 генерирует по умолчанию:

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 нам нужна функция, которая формулирует «приветствие». Эта функция может принимать аргумент для имени, с которым можно поздороваться, и мы хотим записать это имя в верхний регистр.

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

test('generates a label', () => { const result = label("React"); expect(result).toEqual("Hello REACT");
});

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

React, TypeScript и TDD

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

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

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

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:

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

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

Заключение

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

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

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

Автор: Paul Everitt

Источник: dev.to

Редакция: Команда webformyself.

Читайте нас в Telegram, VK, Яндекс.Дзен