Загрузка...

пятница, 8 января 2010 г.

Тестируем проекты на Javascript

Без тестирования собственных продуктов сегодня не обойтись. Я интересуюсь этой темой по насущной проблеме: проект растет большими темпами, но при этом хочется, чтобы добавление нового функционала проходило с минимальными затратами. А получается, что изменив одно, ломается другое. На поиск конфликтов уходит время. С юнит-тестами можно понять, в каком месте сбоит, и, в итоге, быстрее разрешить ситуацию. И не стоит говорить, что само написание тестов уже трата времени. Нет. В дальнейшем только скажешь себе спасибо за уверенность при коммите очередного фикса.

Переходя от философии к теории замечу, что для многих языков уже сложились свои признанные средства тестирования (здесь и далее речь идет о юнит-тестах). Но в отношении JS не все так просто.

Существуют портированные варианты популярных продуктов (например, JsUnit по аналогии с CppUnit), но они не учитывают особенности самого языка. Да и сам язык накладывает на средства свои ограничения. Самое главное — невозможность подгружать файлы. Есть конечно обходные пути, будь то использование тэга <script>, но все-таки это изврат чистой воды. Как выход — использовать небраузерные интерпретаторы яваскрипта. Самый популярный — Mozilla Rhino. Rhino расширяет функционал языка: импорт файлов, вывод на консоль и др., все что нам требуется.

Кстати. Вы в курсе, что Rhino поставляется в пакете с Java SE (начиная с 6 версии)? Это позволяет расширять функционал java-решения скриптовыми вставками. Мне от этого не теплее, но факт остается фактом :)

Но Rhino не панацея. Необходимо использовать толковое средство тестирования. Как оказалось, их существует приличное количество — от самых простых до серьезных. Обзор некоторых из них можно почитать в Википедии или в статье JavaScript Unit Testing блога DailyJS. Именно та статья вывела меня на просто гениальное решение — JSpec.
JSpec is a minimalistic JavaScript behavior driven development framework, providing simple installation, extremely low learning curve, absolutely no pollution to core prototypes, async request support, and incredibly sexy syntax, tons of matchers and much more.

Как видите, тут вам и BDD, удобство использования, и секси синтаксис. Последнее — это вообще отдельный разговор, потому что синтаксис — чистый DSL (помните CoffeeScript?).

Посмотрите на примеры:

describe 'ShoppingCart'
  before_each
    cart = new ShoppingCart
  end

  describe 'addProducts'
    it 'should add several products'
      cart.addProduct('cookie')
      cart.addProduct('icecream')
      cart.should.have 2, 'products'
    end
  end

  describe 'checkout'
    it 'should throw an error when checking out with no products'
      -{ cart.clear().checkout() }.should.throw_error EmptyCart
    end
  end
end

Как говорится, inspired by Ruby. Точнее, это аналог RSpec для Руби. Мало того, этот инструмент может быть установлен как гем. Это позволяет работать с ним не только в браузере, но и в консоли. Чтобы приступить, нужно совсем немного:

sudo gem install jspec
jspec init myproject
cd myproject
jspec run --rhino

Rhino устанавливается автоматически. Вместо последней строчки, можно использовать более общую команду jspec. Она позволяет в фоне следить за изменениями, и отправлять сообщения через Growl (фича для пользователей MacOS).
 Хочу вас сразу предупредить, что JSpec некорректно работает с Руби 1.91 — используйте 1.86. И да, так как сам автор не пользуется виндоподобными операционными системами, то существуют некоторые проблемы с отображением в консоли cmd. Чтобы это исправить, надо заменить функцию color.
Если вас заинтересовал JSpec, то прошу на официальную страницу за дальнейшими разъяснениями.

Мне нравится в нем а) синтаксис, б) удобство, в) простота. А больше и ничего не надо :)

Официальная страница JSpec
Пример использования

blog comments powered by Disqus


 
^

Powered by BloggerCreative Commons License