Статьи

Тестирование вашего JavaScript с жасмином

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

Кстати, вы знали, что специалист по Envato Studio может быстро и легко исправить ошибки JavaScript?

Например , ThemeManiac исправит ошибки JavaScript или проблемы совместимости браузера на вашем веб-сайте или в веб-приложении. Исправления могут быть выполнены очень быстро, в зависимости от сложности и доступной информации. Он также может реорганизовать ваши скрипты и создать совершенно новый пользовательский интерфейс. Он выполнил более 1000 рабочих мест в Envato Studio, и 99% клиентов рекомендуют его.

ThemeManiac на Envato Studio исправит ошибки JavaScript

Сегодня мы будем изучать среду тестирования BDD Jasmine . Но сначала мы остановимся здесь, чтобы очень кратко рассказать о BDD и TDD. Если вы не знакомы с этими аббревиатурами, они означают разработку на основе поведения и разработку на основе тестирования . Я нахожусь в процессе изучения того, что каждый из них на практике и чем они отличаются, но вот некоторые из основных отличий:

BDD и TDD… означают разработку на основе поведения и разработку на основе тестирования .

TDD в простейшем виде это просто:

  1. Напишите свои тесты
  2. Смотреть их не удастся
  3. Заставь их пройти
  4. Refactor
  5. Повторение

Это довольно легко понять, а?

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

  • Установление целей различных заинтересованных сторон, необходимых для реализации видения
  • Вовлечение заинтересованных сторон в процесс внедрения путем разработки программного обеспечения извне
  • Использование примеров для описания поведения приложения или единиц кода
  • Автоматизация этих примеров для обеспечения быстрой обратной связи и регрессионного тестирования

Чтобы узнать больше, вы можете прочитать обширную статью в Википедии (из которой были взяты эти пункты).

Все это говорит о том, что, хотя Jasmine объявляет себя платформой BDD, мы будем использовать ее в стиле TDD. Это не значит, что мы используем это неправильно. Как только мы закончим, вы сможете с легкостью протестировать свой JavaScript … и я ожидаю, что вы сделаете это!


Жасмин берет много подсказок от Rspec.

Если вы вообще знакомы с Rspec, де-факто платформой BDD, вы увидите, что Jasmine берет много подсказок от Rspec. Тесты Жасмин в основном состоят из двух частей: describe блоки и блоки. Посмотрим, как это работает.

Мы рассмотрим несколько более приближенных к реальной жизни тестов, но сейчас мы сделаем это просто:

Функции description и it принимают два параметра: текстовую строку и функцию. Большинство тестовых фреймворков стараются читать как можно больше на английском, и вы можете увидеть это с помощью Jasmine. Во-первых, обратите внимание, что строка, переданная для describe и строка, переданная it образуют предложение (своего рода): «Оператор сложения JavaScript добавляет два числа вместе». Затем мы продолжим, чтобы показать как.

Внутри этого блока вы можете написать весь код установки, необходимый для вашего теста. Нам не нужно ничего для этого простого примера. Когда вы будете готовы написать реальный тестовый код, вы начнете с функции expect , передавая все, что вы тестируете. Обратите внимание, как это также формирует предложение: мы «ожидаем, что 1 + 2 будет равно 3».

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

Я думаю, что вы готовы перейти на следующий уровень, поэтому давайте настроим простой проект с использованием Jasmine.


Жасмин может быть использован сам по себе; или вы можете интегрировать его с проектом Rails. Мы сделаем первое. В то время как Jasmine может работать вне браузера (например, Node, в других местах), мы можем получить действительно хороший маленький шаблон с загрузкой.

Итак, зайдите на отдельную страницу загрузки и получите последнюю версию. Вы должны получить что-то вроде этого:

Жасмин Скачать

Вы найдете актуальные файлы Jasmine Framework в папке lib . Если вы предпочитаете структурировать свои проекты по-другому, пожалуйста, сделайте это; но мы собираемся сохранить это сейчас.

На самом деле в этом шаблоне проекта есть образец кода. «Фактический» JavaScript (код, который мы хотим протестировать) можно найти в подкаталоге src ; мы скоро разместим наш там. Код тестирования — спецификации — находится в папке spec . SpecHelper.js не беспокойтесь о файле SpecHelper.js ; мы вернемся к этому.

Этот файл SpecRunner.html запускает тесты в браузере. Откройте его (и установите флажок «пройдено» в правом верхнем углу), и вы должны увидеть что-то вроде этого:

Образцы тестов

Это показывает нам, что все тесты для примера проекта проходят. После того, как вы spec/PlayerSpec.js этот урок, я рекомендую вам открыть файл spec/PlayerSpec.js и просмотреть этот код. Но сейчас давайте попробуем этот материал для написания теста.

  • Создайте convert.js в папке src .
  • Создайте convertSpec.js в папке spec ,
  • Скопируйте файл SpecRunner.html и переименуйте его в SpecRunner.original.html .
  • Удалите ссылки на файлы примеров проектов в SpecRunner.html и добавьте следующие строки:

    1
    2
    <script src=»src/convert.js»><>/script>
    <script src=»spec/convertSpec.js»></script>

Теперь мы готовы создать мини-библиотеку, которая будет конвертировать единицы измерения. Начнем с написания тестов для нашей мини-библиотеки.


Итак, давайте напишем наши тесты, не так ли?

Начнем с этого; мы тестируем нашу библиотеку Convert . Вы заметите, что мы здесь describe утверждения. Это совершенно законно. На самом деле это отличный способ протестировать отдельные функциональные блоки одной и той же кодовой базы. Вместо двух отдельных описательных вызовов для Convert расстояний и объемных преобразований библиотеки Convert , у нас может быть более описательный набор таких тестов.

Теперь о реальных тестах. Я повторю звонки по внутреннему describe для вашего удобства.

Вот наши тесты для преобразования расстояний. Здесь важно что-то заметить: мы еще не написали ни капли кода для нашей библиотеки Convert , поэтому в этих тестах мы делаем больше, чем просто проверяем, работает ли она: мы на самом деле решаем, как она будет использоваться. (и поэтому реализовано). Вот как мы решили сделать наши конверсии:

Да, я согласен с тем, как Jasmine реализовал свои тесты, но я думаю, что это хороший формат. Итак, в этих двух тестах я сделал преобразования самостоятельно (хорошо, с помощью калькулятора), чтобы увидеть, какими должны быть результаты наших вызовов. Мы используем сопоставление toEqual чтобы проверить, прошли ли наши тесты.

Вот тесты объема:

И я собираюсь добавить еще два теста в наш вызов describe верхнего уровня:

Они проверяют наличие ошибок, которые следует выдавать, когда неизвестные единицы передаются либо в функцию Convert либо в метод to . Вы заметите, что я оборачиваю фактическое преобразование в функцию и передаю его expect функции. Это потому, что мы не можем вызывать функцию как expect параметр; нам нужно передать ему функцию и позволить ей вызвать саму функцию. Поскольку нам нужно передать параметр в функцию, мы можем сделать это следующим образом.

toThrow вещь, на которую стоит обратить внимание, это то, что я представляю новый toThrow сопоставления: toThrow , который принимает объект ошибки. Скоро мы рассмотрим еще несколько матчей.

Теперь, если вы откроете SpecRunner.html в браузере, вы получите следующее:

Преобразовать неудачные тесты

Большой! Наши тесты не проходят. Теперь давайте откроем наш файл convert.js и поработаем:

Мы не собираемся обсуждать это, потому что мы изучаем здесь Жасмин. Но вот основные моменты:

  • Мы делаем преобразования, сохраняя преобразование в объекте; Конверсионные числа классифицируются по типу (расстояние, объем, добавьте свое). Для каждого поля измерения у нас есть базовое значение (здесь, в метрах или литрах), в которое все конвертируется. Поэтому, когда вы видите yards: 0.9144 , вы знаете, что это количество ярдов в метре. Затем, чтобы преобразовать ярды в, скажем, сантиметры, мы умножаем yards на первый параметр (чтобы получить количество метров), а затем делим произведение на cm , число метров в сантиметре. Таким образом, нам не нужно хранить показатели конверсии для каждой пары значений. Это также позволяет легко добавлять новые значения позже.
  • В нашем случае мы ожидаем, что переданные единицы будут такими же, как ключи, которые мы используем в «таблице преобразования». Если бы это была настоящая библиотека, мы бы хотели поддерживать несколько форматов, например «in» , ‘inch’ и ‘дюймов’ — и поэтому мы хотели бы добавить некоторую логику, чтобы сопоставить fromUnit с правой клавишей.
  • В конце функции Convert мы сохраняем промежуточное значение betweenUnit , которое инициализируется как false . Таким образом, если у нас нет fromUnit , betweenUnit будет false входить в метод to , и поэтому будет betweenUnit ошибка.
  • Если у нас нет toUnit , будет toUnit другая ошибка. В противном случае мы разделим как необходимое и вернем преобразованное значение.

Теперь вернитесь к SpecRunner.html и перезагрузите страницу. Теперь вы должны увидеть это (после проверки «Показать пройдено»):

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

И теперь, когда вы увидели этот простой пример использования Jasmine, давайте рассмотрим еще несколько функций, которые он предлагает вам.


До сих пор мы использовали два сопоставителя: toEqual и toThrow . Есть, конечно, много других. Вот несколько, которые вы, вероятно, найдете полезными; Вы можете увидеть весь список в вики .

Если вы просто хотите убедиться, что переменная или свойство определены, для этого есть подходящее средство. Есть также один, чтобы подтвердить, что переменная или свойство не undefined .

Если что-то должно быть правдой или ложью, эти сопоставители сделают это.

Для всех, кого ты числишь. Вы знаете, как они работают:

Есть какой-нибудь выходной текст, который должен соответствовать регулярному выражению? Матч toMatch готов и готов.

Этот довольно полезен. Он проверяет, содержит ли массив или строка элемент или подстроку.

Есть также несколько других совпадений, которые вы можете найти в вики . Но что, если вы хотите совпадения, которого не существует? В самом деле, вы должны иметь возможность делать что угодно с некоторым кодом настройки и средствами сопоставления, которые предлагает Jasmine, но иногда лучше абстрагировать часть этой логики, чтобы сделать тест более читабельным. По счастливой случайности (ну, на самом деле нет), Жасмин позволяет нам создавать наших собственных сопоставителей. Но для этого нам нужно сначала немного научиться чему-то другому.

Часто при тестировании кодовой базы вам нужно выполнить несколько строк кода настройки для каждого теста в серии. Было бы больно и многословно копировать это при каждом вызове, поэтому у Jasmine есть небольшая удобная функция, которая позволяет нам назначать код для запуска до или после каждого теста. Давайте посмотрим, как это работает:

В этом надуманном примере вы можете видеть, как перед каждым тестом состояние obj устанавливается в «clean». Если мы этого не сделали, то изменения, внесенные в объект в предыдущем тесте, сохраняются в следующем тесте по умолчанию. Конечно, мы могли бы сделать нечто подобное с функцией AfterEach :

Здесь мы настраиваем объект для начала, а затем корректируем его после каждого теста. Если вам нужна функция MyObject чтобы вы могли попробовать этот код, вы можете получить ее здесь, в GitHub .

Как мы уже говорили ранее, клиенты, вероятно, будут полезны время от времени. Итак, давайте напишем один. Мы можем добавить сопоставление в вызове BeforeEach или вызове it (ну, я думаю, вы могли бы сделать это в вызове AfterEach , но это не имело бы особого смысла). Вот как вы начинаете:

Довольно просто, а? Мы вызываем this.addMatchers , передавая ему объектный параметр. Каждый ключ в этом объекте станет именем сопоставителя, и связанная с ним функция (значение) будет определять способ его запуска. Допустим, мы хотим создать сопоставление с проверкой, чтобы увидеть, находится ли одно число между двумя другими. Вот что вы написали бы:

Мы просто берем два параметра, проверяем, что первый меньше второго, и возвращаем логическое выражение, которое оценивается как true, если наши условия выполнены. Здесь важно отметить, как мы получаем значение, которое было передано expect функции: this.actual .

Это то, что SpecHelper.js файл SpecHelper.js ; у него есть вызов beforeEach который добавляет tobePlaying() . Проверьте это!


С Jasmine вы можете сделать гораздо больше: сопоставители функций, шпионы, асинхронные спецификации и многое другое. Я рекомендую вам изучить вики, если вам интересно. Есть также несколько сопутствующих библиотек, которые облегчают тестирование в DOM: Jasmine-jQuery и Jasmine-fixture (зависит от Jasmine-jQuery).

Так что, если вы пока не тестируете свой JavaScript, самое время начать. Как мы уже видели, быстрый и простой синтаксис Jasmine делает тестирование довольно простым. У тебя просто нет причин не делать этого сейчас, не так ли?

Если вы хотите продолжить разработку JavaScript, почему бы не проверить ассортимент элементов JavaScript на Envato Market? Существуют тысячи сценариев, приложений и фрагментов кода, чтобы помочь вам.