Среда тестирования

Как было сказано в разделе «Что такое тестирование» , тесты в JavaScript — это, по сути, просто код, который, как мы подтверждаем, работает успешно, то есть без выдачи Error . Однако одна из причин, по которой это определение является чрезмерным упрощением, заключается в том, что оно не учитывает , где мы запускаем код, и его среду тестирования .

Среду тестирования можно в целом рассматривать как два компонента: среду выполнения, которую вы используете для запуска теста (например, Node или браузер), а также доступные вам API.

Среда выполнения

Среды выполнения, такие как Node, или аналогичные инструменты, такие как Deno или Bun, предназначены для поддержки JS-кода на стороне сервера или общего назначения. Их среды не включают в себя API-интерфейсы, которые вы могли бы ожидать в браузере, такие как создание и работа с элементами DOM и HTML, а также какую-либо концепцию визуального компонента или цели рендеринга (то есть не только элементов, но и визуального рендеринга этих элементов с помощью CSS в область просмотра).

Таким образом, эти среды выполнения общего назначения потерпят неудачу, если вы попытаетесь, например, отобразить элементы React, чтобы их можно было протестировать, поскольку нет доступных объектов document или window .

С другой стороны, если вы запускаете тесты внутри браузера, встроенные API, которые вы можете ожидать от этих сред выполнения, могут быть недоступны без полизаполнения или какой-либо дополнительной работы. Распространенная ошибка — это что-то вроде чтения и записи файлов: просто невозможно import { fs } from 'node:'fs'; внутри браузера и прочитайте файл таким образом в рамках теста.

Эта проблема «веб-» и «бэкенд-API» немного выходит за рамки простого тестирования, потому что может быть неудобно иметь кодовую базу, содержащую как серверную, так и клиентскую части, но она связана с идеей написания тестируемого кода, которую мы и реализуем. Я буду возвращаться к этому курсу снова.

Тестирование алгоритмической или бизнес-логики

Для работы части вашего кода и, следовательно, для тестирования не потребуется импорт ни Node, ни браузера. Это то, чего мы коснемся позже в этом курсе, но структурирование вашей кодовой базы таким образом, чтобы ее чистая « бизнес-логика » была отделена от рендеринга или кода, специфичного для узла, может облегчить тестирование.

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

В этом случае вы можете использовать любую среду для тестирования этого кода: либо в среде выполнения на стороне сервера, либо в браузере. В своем тесте вы можете предоставить помощники, которые сохраняют виртуальный файл в памяти или возвращают данные-заполнители. Подобный помощник можно использовать в тесте, поскольку не так важно, например, проверять, работает ли fs.writeFileSync . Сосредоточьтесь на своем коде и на том, что делает его уникальным или рискованным.

Эмулировать API браузера

Многие платформы тестирования, такие как Vitest, предоставляют вам возможность эмулировать среду API браузера без запуска браузера. Vitest внутри использует библиотеку JSDOM . Это может быть хорошим выбором для простых тестов компонентов, когда накладные расходы на использование браузера высоки.

Общей особенностью любой библиотеки эмуляции является то, что, хотя они и могут эмулировать браузер (например, DOM, элементы и файлы cookie), у них нет визуального компонента. Это означает, что они предоставляют обязательный способ работы с элементами HTML и другими примитивами, но вы не можете отображать выходные данные в изображении или на экране или проверять положение элемента в пикселях на странице.

Опять же, этот выбор может хорошо подойти для тестирования компонентов , где компонент представляет собой элемент React, веб-компонент и т. д. Эти типы компонентов обычно создают и взаимодействуют с DOM относительно небольшим образом, а эмулируемый браузер может предоставить достаточную функциональность, чтобы убедиться, что компонент работает так, как вы хотите. В следующем разделе приведен пример теста компонента React с Vitest и JSDOM.

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

Управляйте настоящим браузером

Чтобы протестировать ваш код так, как его будут воспринимать ваши пользователи, лучше всего использовать настоящий браузер. На практике среды выполнения тестирования, поддерживающие браузер, будут запускать и управлять экземплярами реального браузера, даже если они запускают команду start внутри Node.js.

Управление браузером в рамках теста означает, что он будет открываться так же, как и для пользователя, что позволяет вашему тесту управлять им, загружая URL-адреса, собственный HTML и JS или что-то еще, необходимое для выполнения вашего теста. Затем вы можете написать код, который будет действовать как пользователь, например, управляя мышью или вводя данные в поля ввода.

Современные инструменты, такие как WebdriverIO или Web Test Runner , могут контролировать все основные браузеры и даже запускать несколько экземпляров одновременно. Эти браузеры могут работать рядом с программой запуска тестов (например, на вашем собственном компьютере или в рамках действия CI) или быть переданы на аутсорсинг внешним коммерческим службам, которые будут запускать их за вас.

Более известные библиотеки тестирования (включая Vitest и Jest) часто имеют режим браузера, но поскольку они происходят из Node.js, их режимы браузера часто «прикручены» и в них отсутствуют полезные функции. Например, Vitest не может имитировать импорт модулей в браузере — мощный примитив, который мы используем в примере на следующей странице.

На практике

По мере того, как ваши тесты становятся все сложнее, использование настоящего браузера становится все более важным.

  • Для тестов, которые не используют или используют минимальные функции DOM, даже функции, доступные в Node.js и аналогичных средах выполнения, таких как fetch или EventTarget , среда не имеет значения.
  • Для небольших тестов компонентов может подойти JSDOM.
  • Более крупные тесты — например, сквозные тесты , которые могут имитировать вход пользователя в систему и выполнение основного действия — имеет смысл полностью запускать в реальном браузере.

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

Проверьте свое понимание

Какие функции браузера *не* поддерживает уровень эмуляции jsdom?

Механизм компоновки.
Поскольку JSDOM не является визуальным инструментом, его нельзя использовать для проверки положения элемента на странице, его разрешенных атрибутов CSS или любых других частей макета веб-сайта.
Вебсокет
JSDOM включает в себя полифил WebSocket, поэтому код, использующий его, будет работать.
requestAnimationFrame
С флагом pretendToBeVisual jsdom будет вызывать обратный вызов анимации со скоростью 60 кадров в секунду, даже если на самом деле ничего не рисуется.