Разработка через тестирование: улучшаем навыки. Часть 2

В предыдущей статье мы рассмотрели теоретические аспекты. Самое время приступить к практике.

Разработка через тестирование: улучшаем навыки. Часть 2

Сделаем простую реализацию стека в JavaScript с помощью разработки через тестирование.

Стек — структура данных, организованная по принципу LIFO: Last In, First Out. В стеке есть три основные операции:

push: добавление элемента

pop: удаление элемента

peek: добавление головного элемента

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

items: элементы стека. Мы будем использовать массив для реализации стека.

capacity: вместимость стека.

isEmpty(): возвращает true, если стек пуст, иначе false.

isFull(): возвращает true, если стек достигает максимальной емкости, т.е. когда вы не можете добавить другой элемент. В противном случае возвращает false.

push(element): добавляет элемент. Возвращает Full, если стек переполнен.

pop: удаляет элемент. Возвращает Empty, если стек пуст.

peek(): добавляет головной элемент.

Мы собираемся создать два файла stack.js и stack.spec.js. Я использовал расширение .spec.js, потому что привык к нему, но вы можете использовать .test.js или дать ему другое имя и переместить в __tests__.

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

Сначала проверим конструктор. Чтобы протестировать файл, вам необходимо импортировать файл стека:

Разработка через тестирование: улучшаем навыки. Часть 2

Для тех, кому интересно, почему я не использовал здесь import— последняя стабильная версия Node.js не поддерживает эту функцию на сегодняшний день. Я мог бы добавить Babel, но не хочу перегружать вас. Когда вы тестируете класс или функцию, запустите тест и опишите, какой файл или класс вы тестируете. Здесь речь идет о стеке:

Разработка через тестирование: улучшаем навыки. Часть 2

Затем нам нужно проверить, что при инициализации стека создается пустой массив, и мы устанавливаем правильную вместимость. Итак, пишем следующий тест:

Разработка через тестирование: улучшаем навыки. Часть 2

Заметьте, что мы используем toEqual и не используем toBe для stack.items, потому что они не ссылаются на один и тот же массив.Теперь запустим yarn test stack.spec.js. Мы запускаем Jest в определенном файле, потому что мы не хотим, чтобы другие тесты были испорчены. Вот результат:

Разработка через тестирование: улучшаем навыки. Часть 2

Stack is not a constructor. Конечно. Мы до сих пор не создали наш стек и не сделали constructor. В stack.js создайте свой класс, конструктор и экспортируйте класс:

Разработка через тестирование: улучшаем навыки. Часть 2

Запустите тест снова:

Разработка через тестирование: улучшаем навыки. Часть 2

Поскольку мы не устанавливали элементы в конструкторе, Jest ожидал, что элементы в массиве будут равны [], но они не определены. Затем вы должны инициализировать элементы:

Разработка через тестирование: улучшаем навыки. Часть 2

Если вы снова запустите тест, вы получите такую же ошибку для capacity, поэтому вам также нужно будет установить вместимость:

Разработка через тестирование: улучшаем навыки. Часть 2

Запустим тест: Да! Тест пройден. Вот что такое TDD. Надеюсь, теперь тестирование будет иметь для вас больше смысла! Продолжим?

isEmpty

Чтобы проверить isEmpty, мы собираемся инициализировать пустой стек, протестировать, если isEmpty возвращает true, добавить элемент и снова проверить его.

Разработка через тестирование: улучшаем навыки. Часть 2

Когда вы запустите тест, вы должны получить следующую ошибку:

Разработка через тестирование: улучшаем навыки. Часть 2

Чтобы решить эту проблему, нам надо создать isEmpty внутри класса Stack:

Разработка через тестирование: улучшаем навыки. Часть 2

Если вы запустите тест, вы должны получить еще одну ошибку:

Разработка через тестирование: улучшаем навыки. Часть 2

В isEmpty ничего не добавляется. Stack пуст, если в нем нет элементов:

Разработка через тестирование: улучшаем навыки. Часть 2

isFull

Это то же самое, что и isEmpty, так как это упражнение проверяет эту функцию с помощью TDD. Вы найдете решение в самом конце статьи.

Push

Здесь нам надо протестироватьтривещи:

  • новый элемент должен быть добавлен в начало стека;
  • push возвращает «Full», если стек заполнен;
  • элемент, который был недавно добавлен, должен быть возвращен.

Создадим другой блок, используя describe для push. Вкладываем этот блок внутри основного.

Разработка через тестирование: улучшаем навыки. Часть 2

Добавление элемента

Создадим новый стек и добавим элемент. Последним элементом массива items должен быть только что добавленный элемент.

Разработка через тестирование: улучшаем навыки. Часть 2

Если вы запустите тест, то увидите, что push не определен и это нормально. push потребуется параметр, чтобы что-то добавить в стек:

Разработка через тестирование: улучшаем навыки. Часть 2

Тест снова пройден. Вы что-то заметили? Мы сохраняем копию этой строки:

Разработка через тестирование: улучшаем навыки. Часть 2

Это очень раздражает. К счастью, у нас есть метод beforeEach, который позволяет выполнять некоторую настройку перед каждым тестовым прогоном. Почему бы не воспользоваться этим?

Разработка через тестирование: улучшаем навыки. Часть 2

Важно:

стек должен быть объявлен раньше beforeEach. В самом деле, если вы определяете его в методе beforeEach, переменная стека не будет определена во всех тестах, потому что она не находится в правильной области.

Важнее важного:

мы также должны создать метод afterEach. Экземпляр стека теперь будет использоваться для всех тестов. Это может вызвать некоторые трудности. Сразу после beforeEach добавьте этот метод:

Разработка через тестирование: улучшаем навыки. Часть 2

Теперь вы можете удалить инициализацию стека во всех тестах. Вот полный тестовый файл:

Разработка через тестирование: улучшаем навыки. Часть 2

Тестирование возвращаемого значения

Есть тест:

Разработка через тестирование: улучшаем навыки. Часть 2

Когда вы запустите тест, получите:

Разработка через тестирование: улучшаем навыки. Часть 2

Ничего не возвращается внутри push! Мы должны исправить это:

Разработка через тестирование: улучшаем навыки. Часть 2

Возвращение full, если стек переполнен

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

Разработка через тестирование: улучшаем навыки. Часть 2

Вы увидите эту ошибку, когда запустите тест:

Разработка через тестирование: улучшаем навыки. Часть 2

Итак, элемент добавлен. Это то, что мы и хотели. Сначала нужно проверить, заполнен ли стек, прежде чем добавить что-то:

Разработка через тестирование: улучшаем навыки. Часть 2

Тест пройден.

Упражнение: pop и peek

Самое время попрактиковаться. Протестируйте и реализуйте pop и peek.

Подсказки:

  • pop очень похожа на push
  • peek также похожа на push
  • До сих пор мы не рефакторили код, потому что в этом не было необходимости. В этих функциях может быть способ рефакторить ваш код после написания тестов и их прохождения. Не беспокойтесь, изменяя код, тесты для того и нужны.

Не смотрите на решение ниже, не попытавшись сделать самостоятельно. Единственный способ прогресса — пытаться, экспериментировать и практиковаться.

Решение

Ну как упражнение? Справились? Если нет, не расстраивайтесь. Тестирование требует времени и усилий.

Разработка через тестирование: улучшаем навыки. Часть 2
Разработка через тестирование: улучшаем навыки. Часть 2
Разработка через тестирование: улучшаем навыки. Часть 2

Если вы посмотрите на файлы, вы увидите, что я использовал тройное условие в pop и peek. Это то, что я рефакторил. Старая реализация выглядела так:

Разработка через тестирование: улучшаем навыки. Часть 2

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

Запустим тест еще раз:

Разработка через тестирование: улучшаем навыки. Часть 2

Тесты улучшают качество кода. Надеюсь, вы теперь понимаете всю пользу тестирования и будете чаще применять TDD.

1 комментарий

Хабровчане потихоньку переезжают на Виси?

1