Простая среда тестирования JavaScript с нуля

В этой статье я создаю простой JavaScript-фреймворк с нуля. Затем фреймворк будет использоваться для самого модульного тестирования.

Цель состоит в том, чтобы запустить это:

Давайте начнем. Полный исходный код находится здесь, а тесты - здесь.

Создайте новый файл с именем index.js. Здесь будет находиться весь исходный код. Начнем с describe.

Описывать

Подпись функции describe - fn(description, callback). Первый аргумент - это просто строка, описывающая блок, а callback содержит фактический тестовый код для выполнения. Также неплохо было бы распечатать описание при выполнении теста.

Относительно просто! Еще одна приятная часть этого - мы можем иметь произвольно вложенные describe блоки. Например:

На удивление просто. Двигаемся дальше…

it

it на самом деле проще реализовать, чем describe, по крайней мере, для этого примера. Почему? Давайте посмотрим на сигнатуру функции. Первый аргумент - это сообщение, а второй - обратный вызов:

fn(description, callback)

… Что идентично describe. Давайте просто воспользуемся describe!

Теперь нам просто нужно реализовать expect(....).toBe(...).

ожидать

Начнем с expect. Сигнатура функции следующая:

expect(value).toBe(value)

Поскольку мы хотим объединить .toBe в цепочку, expect должен возвращать объект, имеющий toBe property, который является методом.

Начнем с определения метода expect:

Теперь мы можем ввести expect(1). Нам просто нужен объект со свойством toBe, который сравнивает значение, переданное в expect, и значение, переданное в toBe.

сопоставители

Объект, возвращаемый expect, будет содержать по крайней мере одно сопоставление, toBe и, возможно, больше в будущем. Это выглядит так:

exp - это ожидаемое значение, которое передается в expect. Нам нужно передать его в matchers, чтобы иметь возможность провести сравнение. toBe получает утверждение, которое, как мы ожидаем, будет равно значению, переданному в expect.

toBe выполняет строгое сравнение с использованием ===. Это означает, что toBe можно использовать только для примитивов, таких как String, Number и Boolean.

Это все, что нам нужно, чтобы запустить пример кода с начала статьи! Полный исходный код с примером, приведенным ниже, может быть вставлен в один index.js и запущен с использованием node index.js.

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

Тестирование среды тестирования

Как и было обещано, мы протестируем фреймворк на самом себе. Я напишу тесты в файл с именем index.test.js, который можно запускать с помощью node index.test.js.

Сначала тест на describe.

Описание тестирования

describe… на самом деле мало что делает. Он просто console.log значение и выполняет callback. Мы могли бы издеваться над console.log и убедиться, что он вызывается, но это не очень интересно. Давайте сосредоточимся на том, чтобы убедиться, что обратный вызов вызван.

Мы начинаем с того, что запрашиваем все функции, которые мы будем тестировать (и должны написать тесты). Мы просто объявляем noop или безоперационную функцию, которая увеличивает значение каждый раз при вызове - так мы будем утверждать, что describe вызывает обратный вызов.

Тестирование describe теперь так же просто, как и утверждение, что executes действительно имеет приращения, что свидетельствует о том, что обратный вызов noop действительно был выполнен.

it

Он просто вызывает describe и не делает ничего другого, так что тестирование не очень интересно.

ожидать

expect тоже очень прямолинейный. expect возвращает объект со свойством toBe, равным function.

matchers.toBe

toBe проверить так же просто, как и все остальное. Он должен возвращать true, если примитивы равны, например, 1 === 1, и false для 1 === 2.

Написание false точно такое же, поэтому я не буду его включать.

Заключение и улучшения

index.js, без пробелов и exports, меньше 30 строк кода! Это ни в коем случае не очень полнофункциональный фреймворк, но всего для 30 строк он относительно мощный. Добавление дополнительных сопоставителей так же просто, как добавление дополнительных методов в matchers.

Строения isEqual, isTruthy и тривиальны. Добавьте более продвинутые средства сопоставления, такие как toHaveBeenCalled, и другие функции тестирования, такие как шпионские и имитирующие функции, - это некоторые улучшения, которые я хотел бы реализовать, а также лучшую обработку ошибок и средство ведения журнала.

✉️ Подпишитесь на рассылку еженедельно Email Blast 🐦 Подпишитесь на CodeBurst на Twitter , просмотрите 🗺️ Дорожная карта веб-разработчиков на 2018 год и 🕸️ Изучите веб-разработку с полным стеком .