От автора: 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 для получения и запуска пакета) очень просто:
1 |
$ npx create-react-app my-app --template typescript |
Современные IDE, вероятно, автоматизируют это за вас как часть мастера New Project. Затем npx получит пакет create-response-app, запустит его и передаст аргумент шаблона, говорящий о создании пакета, использующего TypeScript. Вы, вероятно, будете смеяться над этим самоуверенным сообщением журнала:
1 |
Installing packages. This might take a couple of minutes. |
Команда также инициализирует репозиторий git, создает package.json и выполняет эквивалент npm install для созданного вами пакета. На момент написания этой статьи в каталоге node_modules было всего 1063 записи. Спасибо CRA, за то, что управляет всем этим.
Теперь у вас есть рабочий Hello World на React и TypeScript. Чтобы увидеть его в действии, запустите:
1 |
$ npm start |
В вашей IDE, вероятно, есть способ запустить это с помощью клика мышью. Например, в WebStorm и других IDE IntelliJ:
Вы увидите несколько сообщений журнала при запуске сервера разработки, и браузер откроется по адресу http://localhost:3000 — удобно! Откуда «начало»? Взгляните на блок «scripts» в сгенерированном файле package.json:
1 |
"start": "react-scripts start", |
Это ярлык для консольного скрипта, предоставленного CRA.
Но подождите, это еще не все! Пока сервер разработки все еще работает, откройте файл src/App.tsx и добавьте текст <p>, затем сохраните. Через секунду или две ваш браузер покажет обновление. CRA следит за изменениями, прозрачно выполняет четыре триллиона инструкций по изменению кода внешнего интерфейса и выполняет интеллектуальную перезагрузку с помощью браузера.
Если вы посмотрите на package.json, то увидите, что он довольно компактен.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
{ "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:
1 |
$ npm run-script build |
Это займет некоторое время, так как он гипероптимизирует сгенерированный сайт / приложение React в каталоге build. Затем его можно развернуть на сервере.
Привет, тест
«Вы меня взволновали тестированием, а не тестированием, а где тестирование!» Вы правы! Давайте проведем небольшое тестирование, следуя этому руководству.
Во-первых, немного предыстории. Знаю, знаю, скоро пройду тест. CRA самодостаточен. Он выбирает важные пакеты, генерирует конфигурацию и поддерживает работу установки. Для тестировани CRA использует три важных инструмента:
Фреймворк тестирования Jest
jsdom как смоделированный браузер
React-testing-library как библиотеку утверждений
Достаточно церемонии. Запустим тесты:
1 |
$ npm run-script test |
Вы получите сообщение, что у CRA нет тестов, которые изменились на основе Git:
Откройте src/app/App.tsx и измените save to reload на save to reload!!. Вы увидите, что результат выглядит примерно так:
У наблюдателя есть несколько вариантов ограничения того, что он ищет, что действительно помогает продуктивности. На этот раз замените «Learn React» в src/App.tsx на «Master React». Наблюдатель повторно запускает тесты, которые теперь не работают:
В среде IDE вы можете взглянуть на это более подробно. Например, вот как выглядит результат провального теста в WebStorm:
Что здесь на самом деле происходит? Что исполняется? Как упоминалось ранее, CRA использует Jest для выполнения теста. Это делает Jest … подождите … тест- раннер. Он предоставляет конфигурацию, командные флаги (например, наблюдатель), способы поиска тестов и т. Д. Он также связывает jsdom в качестве предварительно настроенной тестовой среды , что далеко от слова «браузер».
jsdom действительно хорош. Это поддельный браузер, написанный на JS, который работает на NodeJS и делает вид, что отображает вашу разметку и выполняет ваш JavaScript. Это сверхбыстрая ненавязчивая альтернатива запуску Chrome для каждого теста.
Jest также использует библиотеку тестирования — в частности, ее интеграцию с React — для формата тестов и утверждений, в которых вы проверяете, что код работает.
На что это похоже? Как выглядит настоящий тест? Вот тест, который Create React App генерирует по умолчанию:
1 2 3 4 5 6 7 8 9 |
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 нам нужна функция, которая формулирует «приветствие». Эта функция может принимать аргумент для имени, с которым можно поздороваться, и мы хотим записать это имя в верхний регистр.
Мы могли бы написать функцию и вставить вызов в заголовок. Но давайте сначала напишем тест:
1 2 3 4 |
test('generates a label', () => { const result = label("React"); expect(result).toEqual("Hello REACT"); }); |
Тест не пройден: мы не написали функцию формирования label. Фактически, наш инструмент предупредил нас, что мы его даже не импортировали:
Теперь напишем функцию формирования label:
1 2 3 |
export function label(name) { return `Hello ${name.toUpperCase()}`; } |
Как только мы ее импортируем в src/App.test.tsx, тесты начнут проходить. Это здорово, но если мы передадим функции целое число вместо строки:
1 2 3 4 |
test('generates a label', () => { const result = label(42); expect(result).toEqual("Hello REACT"); }); |
… тест рассердится:
Допустим, мы не можем легко решить проблему. Вместо того, чтобы разбрызгивать console.log повсюду, мы можем использовать … отладчик! Установите точку останова на строке в тесте:
Теперь запустим тесты, но под отладчиком:
Выполнение остановится на этой строке в тесте. Вы можете выбрать «Шаг с заходом», чтобы перейти к функции label, а затем в интерактивном режиме перемещаться по ней. Затем вы обнаружите — у целых чисел нет метода toUpperCase:
Фактически, TypeScript предупреждал нас об этом:
Чтобы защититься от этого в будущем, добавьте информацию о типе в аргумент имени функции label:
1 2 3 |
export function label(name: string) { return `Hello ${name.toUpperCase()}`; } |
Отладка во время написания теста — и оставаясь в NodeJS, то есть в вашем инструменте — очень продуктивна. Это намного продуктивнее, чем вселенная console.log или использование отладчика браузера.
Заключение
Написание компонентов React обычно представляет собой итеративный процесс: напишите код, переключитесь в браузер, кликнете мышью. Когда у тебя проблемы и нужно ковыряться, это … сложно.
Комбинация TypeScript, «сначала тестирование» и более интеллектуальных инструментов дает альтернативу. Ту, где вы «быстрее фейлитесь» но продолжаете писать код, кодируете с уверенностью — и, смею вам сказать, получайте больше удовольствия.
В этой первой части мы разобрались с базовыми вещами. Как показано в руководстве, в следующих двух частях мы перейдем к реальной разработке компонентов.
Автор: Paul Everitt
Источник: dev.to
Редакция: Команда webformyself.
Читайте нас в Telegram, VK, Яндекс.Дзен