Сравнение инфраструктуры тестирования JavaScript: Жасмин против Мокко

  1. 1. API
  2. 2. Test Doubles
  3. 3. Асинхронное тестирование
  4. 4. Синон Поддельный Сервер
  5. 5. Запуск тестов
  6. Резюме
  7. об авторе

(фото tdlucas5000 )

Тестирование на JavaScript становится все более и более ожидаемым разработчиками. Но с чего начать? Существует так много вариантов рамок. Это может быть довольно подавляющим. Этот пост представляет собой краткий обзор различий между двумя популярными средами тестирования JavaScript: Жасмин 2 а также кофе мокко , Мы также обсудим часто используемые библиотеки, Chai а также Sinon , которые часто используются в сочетании с жасмином и мокко.

1. API

API-интерфейсы Jasmine и Mocha очень похожи, когда вы пишете свой набор тестов с блоками описания, а каждый тест, также называемый спецификацией, использует функцию it.

description ('calculator add ()', function () {it ('должно добавить 2 числа к тому же эфиру', function () {// здесь утверждения});});

Утверждения, или ожидания, как их часто называют, - вот где вещи начинают различаться. Mocha не имеет встроенной библиотеки утверждений. Есть несколько вариантов для Node и для браузера: Chai, should.js, hope.js и better-assert. Многие разработчики выбирают Чай как свою библиотеку утверждений. Поскольку ни одна из этих библиотек утверждений не поставляется с Mocha, это еще одна вещь, которую вам нужно будет загрузить в свой тестовый комплект. Чай имеет три разных вкуса. У него есть стиль must, ожидаемый стиль и стиль assert. Стиль ожидания похож на тот, что предлагает Жасмин. Например, если вы хотите написать ожидание, которое проверяет, что calculator.add (1, 4) равен 5, это то, как вы бы сделали это с Jasmine и Chai:

жасмин

ожидайте (calculator.add (1, 4)). toEqual (5);

Chai

ожидайте (calculator.add (1, 4)). to.equal (5);

Довольно похоже, верно? Если вы переходите с жасмина на мокко, путь с самой легкой кривой обучения - это использование чая с ожидаемым стилем. В Jasmine методы утверждения, такие как toEqual (), используют случай верблюда, тогда как комплимент в Chai использует точечную нотацию to.equal (). И Жасмин, и Мокко используют функции description () и it ().

2. Test Doubles

Тестовые удвоения часто сравнивают с двойниками каскадеров, поскольку они заменяют один объект другим для целей тестирования, подобно тому, как актеры и актрисы заменяются двойниками каскадеров для опасных сцен действия. В Жасмин тестовые двойники приходят в форме шпионов. Шпион - это функция, которая заменяет определенную функцию, где вы хотите контролировать ее поведение в тесте и записывать, как эта функция используется во время выполнения этого теста. Вот некоторые вещи, которые вы можете сделать со шпионами:

  • Посмотрите, сколько раз был вызван шпион
  • Укажите возвращаемое значение, чтобы заставить ваш код идти по определенному пути
  • Скажите шпиону, чтобы он сгенерировал ошибку
  • Посмотрите, с какими аргументами был вызван шпион
  • Скажите шпиону, чтобы он вызвал исходную функцию (функцию, за которой он следит). По умолчанию шпион не будет вызывать исходную функцию.

В Жасмин, вы можете следить за существующими методами, как это:

var userSaveSpy = spyOn (User.prototype, 'save');

Вы также можете создать шпиона, если у вас нет существующего метода, на который вы хотите шпионить.

var spy = jasmine.createSpy ();

Напротив, Mocha не поставляется с тестовой двойной библиотекой. Вместо этого вам нужно будет загрузить Sinon в ваш тестовый комплект. Sinon - очень мощная двойная библиотека для тестирования и эквивалент шпионов Jasmine с немного большим количеством. Стоит отметить, что Sinon разбивает тестовые двойники на три категории: шпионы , заглушки , а также издевается , каждый с тонкими различиями.

Шпион в Sinon вызывает метод, за которым следят, в то время как вы должны указать это поведение в Jasmine. Например:

spyOn (user, 'isValid'). andCallThrough () // Jasmine // эквивалентен sinon.spy (user, 'isValid') // Sinon

В вашем тесте будет вызван оригинальный user.isValid.

Следующий тип двойного теста - заглушка, которая действует как контролируемая замена. Заглушки похожи на поведение по умолчанию шпионов Жасмин, когда оригинальный метод не вызывается. Например:

sinon.stub (пользователь, 'isValid'). return (true) // Sinon // эквивалентен spyOn (user, 'isValid'). andReturns (true) // Jasmine

В вашем коде, если user.isValid вызывается во время выполнения ваших тестов, оригинальный user.isValid не будет вызываться, и будет использоваться поддельная его версия (test double), которая возвращает true. В Sinon заглушка - это тестовый двойник, построенный поверх шпионов, поэтому заглушки могут записывать, как используется функция.

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

Исходя из моего опыта, шпионы Жасмин покрывают почти все, что мне нужно для двойников, поэтому во многих ситуациях вам не нужно будет использовать Sinon, если вы используете Jasmine, но вы можете использовать их вместе, если хотите. Одна из причин, по которой я использую Sinon с Jasmine, - это его поддельный сервер (подробнее об этом позже).

3. Асинхронное тестирование

Асинхронное тестирование в Jasmine 2.x и Mocha одинаково.

это ('должно разрешиться с помощью объекта User', функция (сделано) {var dfd = new $ .Deferred (); var обещание = dfd.promise (); var stub = sinon.stub (User.prototype, 'fetch') .returns (обещание); dfd.resolve ({имя: 'Дэвид'}); User.get (). then (функция (пользователь) {ожидание (пользовательский экземпляр пользователя) .toBe (истина); done ();}) ;});

Выше User является функцией конструктора со статическим методом get. За кулисами get использует fetch, которая выполняет запрос XHR. Я хочу утверждать, что когда get разрешается успешно, разрешенное значение является экземпляром User. Поскольку я отключил User.prototype.fetch для возврата предварительно разрешенного обещания, настоящий запрос AJAX не выполняется. Тем не менее, этот код все еще асинхронный.

Просто указав параметр в функции обратного вызова it (я назвал его как в документации, но вы можете вызывать его как угодно), тестовый исполнитель передаст функцию и будет ждать выполнения этой функции перед завершением теста. Тест остановится и произойдет ошибка, если выполнение не вызвано в течение определенного периода времени. Это дает вам полный контроль над завершением ваших тестов. Вышеуказанный тест будет работать как в Mocha, так и в Jasmine 2.x.

Если вы работаете с Jasmine 1.3, асинхронное тестирование не было таким приятным.

Пример Jasmine 1.3 Асинхронный тест

it ('должно разрешаться с помощью объекта User'), function () {var flag = false; var david; выполнения (function () {var dfd = new $ .Deferred (); var обещание = dfd.promise (); dfd. resolv ({name: 'David'}); spyOn (User.prototype, 'fetch'). andReturn (обещание); User.get (). then (function (user) {flag = true; david = user;}) ;}); waitsFor (function () {return flag;}, «get должен разрешить с моделью», 500); run (function () {Ожидайте (Дэвид экземпляр пользователя) .toBe (true);});}) ;

В этом примере асинхронного теста Jasmine 1.3 Jasmine будет ожидать максимум 500 миллисекунд для завершения асинхронной операции. В противном случае тест не пройден. waitsFor () постоянно проверяет, становится ли флаг истинным. Как только это произойдет, он продолжит выполнение следующего блока run (), где у меня есть утверждение.

4. Синон Поддельный Сервер

У Синона есть одна особенность, которой нет у Жасмин - это фальшивый сервер. Это позволяет настроить поддельные ответы на запросы AJAX, сделанные для определенных URL-адресов.

it ('должен вернуть объект коллекции, содержащий всех пользователей', function (done) {var server = sinon.fakeServer.create (); server.respondWith ("GET", "/ users", [200, {"Content-Type) ":" application / json "}, '[{" id ": 1," name ":" Gwen "}, {" id ": 2," name ":" John "}]']); Users.all () .done (function (collection) {Ожидайте (collection.toJSON ()). to.eql ([{id: 1, имя: "Гвен"}, {id: 2, имя: "Джон"}]); done ();}); server.respond (); server.restore ();});

В приведенном выше примере, если GET-запрос сделан для / users, будет возвращен ответ 200, содержащий двух пользователей, Gwen и John. Это может быть очень удобно по нескольким причинам. Во-первых, он позволяет вам тестировать свой код, который выполняет вызовы AJAX, независимо от того, какую библиотеку AJAX вы используете. Во-вторых, вы можете протестировать функцию, которая выполняет вызов AJAX и выполняет некоторую предварительную обработку ответа до разрешения обещания. В-третьих, возможно, есть несколько ответов, которые могут быть возвращены в зависимости от того, успешно ли выполнен запрос, например, успешное списание средств с кредитной карты, неверный номер кредитной карты, просроченная карта, недействительный CVC и т. Д. Вы поняли идею. Если вы работали с Angular, фальшивый сервер Sinon похож на сервис $ httpBackend, предоставляемый в angular mocks.

5. Запуск тестов

Mocha поставляется с утилитой командной строки, которую вы можете использовать для запуска тестов. Например:

тесты мокко - рекурсивные - часы

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

Однако у Жасмин нет утилиты командной строки для запуска тестов. Есть тестеры для Жасмин, и очень популярный Карма угловой командой. Карма также позволяет поддерживать Mocha, если вы хотите выполнить свои тесты Mocha таким образом.

Резюме

В заключение, в среду Jasmine встроено практически все, включая утверждения / ожидания и тестирование двойных утилит (которые представлены в форме шпионов). Однако, у него нет тестового бегуна, поэтому для этого вам понадобится такой инструмент, как Karma. Mocha, с другой стороны, включает в себя тестовый прогон и API для настройки вашего набора тестов, но не включает в себя утилиты проверки и двойные утилиты. Существует несколько вариантов утверждений при использовании Мокко, и Чай, как правило, является самым популярным. Для тестовых пар в Mocha также требуется другая библиотека, и Sinon.js часто является де-факто выбором. Sinon также может стать отличным дополнением к вашему тестовому устройству благодаря своей поддельной реализации сервера.

Итак, если бы вы выбрали сегодня тестовую среду, как она может выглядеть?

Если вы идете с Жасмин, вы, вероятно, будете использовать:

  • Карма (для бегуна)
  • Sinon (возможно, для его поддельного сервера, если ваша инфраструктура не предоставляет аналога, например $ httpBackend, если вы используете Angular)

Если вы идете с Мокко, вы, вероятно, будете использовать:

  • Чай (для утверждений)
  • Синон (для тестовых двойников и его фальшивого сервера)
  • Карма или мокко CLI (для бегуна)

Попытка выяснить, как тестировать библиотеки / фреймворки для использования в JavaScript, может быть сложной, но, надеюсь, эта статья прояснила, в чем заключаются некоторые основные различия между Жасмин и Мокко. Вы не можете ошибиться с любым выбором. Важно то, что вы тестируете!

об авторе

об авторе

Дэвид Танг (David Tang) - полный инженер, увлеченный тестированием, архитектурой приложений и созданием отличных пользовательских приложений Дэвид по совместительству читает лекции в Университете Южной Калифорнии и участвовал или создал популярные репозитории, такие как: Restrict, angular-data, validatorjs и Backbone Computed Properties. Найдите больше советов и приемов Дэвида по написанию тестируемого JavaScript на его блог !

Но с чего начать?
Итак, если бы вы выбрали сегодня тестовую среду, как она может выглядеть?