Ruby

индекс
128,98

BDD/TDD — Учимся писать матчеры

Разработка, основанная на специфицировании поведения (BDD), — один из краеугольных камней философии Ruby.

Очень удачной реализацией BDD является всем знакомый RSpec. Одной из замечательных черт RSpec является его расширяемость.

Так, мы используем RSpec совместно с Factory Girl (хотя стоило бы перейти на Machinist), RR (прекрасный каркас для заглушек), Spork и недавно перешли с Shoulda на Remarkable.

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

Хорошим способом сделать это является создание нового «ожидателя» (matcher).



Основная логика заключается в методе is_valid?, который проверяет соответствие субьекта тестирования нашим ожиданиям.

  1. module Scalaxy
  2.   module Matchers
  3.     class CallbackPresenceMatcher < Remarkable::Base
  4.       arguments :chain, :callback
  5.       assertion :is_valid?
  6.     protected
  7.       def is_valid?
  8.         instance = @subject.kind_of?(Class) ? @subject.new : @subject
  9.         chain_name = "#{@chain}_callback_chain".to_sym
  10.         return false unless instance.kind_of?(ActiveSupport::Callbacks)
  11.         return false unless instance.class.respond_to?(@chain)
  12.         return false unless instance.class.respond_to?(chain_name)
  13.         return false if instance.class.send(chain_name).select { |c| c.method == @callback }.empty?
  14.         true
  15.       end
  16.     end
  17.     # Matches for presence of specified callback inside specified callback chain.
  18.     # should_callback_presence :after_run, :notify_people
  19.     def callback_presence(*args)
  20.       CallbackPresenceMatcher.new(*args).spec(self)
  21.     end
  22.   end
  23. end
  24. Remarkable.include_matchers!(Scalaxy, ActiveSupport::TestCase)


Также потребуется расширить файл локали, добавив в него информацию о нашем «ожидателе».
  1. en:
  2.   scalaxy:
  3.     callback_presence:
  4.       description: 'Checks for presence of {{callback}} in specified callback chain {{chain}}.'
  5.       expectations:
  6.         is_valid: "to be valid when {{callback}} in {{chain}}"


И добавить require на наш файл matchers.rb в spec_helper.

И теперь можно легко и просто описывать наши ожидания.
  1. class Thing < ActiveRecord::Base
  2.   ## Callbacks
  3.   define_callbacks :after_run
  4.   after_run :notify_people
  5. end

  1. describe Thing do
  2.   should_callback_presence :after_run, :notify_people
  3. end


______________________
Текст подготовлен в Хабра Редакторе от © SoftCoder.ru
+14
30 октября 2009, 15:44
23

комментарии (14)

0
enej #
Чем Machinist лучше?
0
akzhan #
Поддерживается не только ActiveRecord, но и любые другие классы.

И немного более приятный DSL.
0
hellraiser09 #
Так, мы используем RSpec совместно с Factory Girl (хотя стоило бы перейти на Machinist), RR (прекрасный каркас для заглушек), Spork и недавно перешли с Shoulda на Remarkable.
Это вы с кем сейчас разговаривали?
+3
kronos #
С людьми, которые хоть как-то знакомы с тестированием в Ruby.
–1
ESQUELETO #
Вот этим отличаются рубисты от питонистов. Первые больше дрочат на тестирование, чем тестируют.

Поэтому я и живу меж двух станов :-)
+1
kossnocorp #
Спасибо что рассказали, а то я думал чем же они отличаются %)
+2
bolkhovsky #
Спасибо за статью. Может, напишете более развернутую статью о TDD/BDD в ruby/rails, с самого начала, как вы это практикуете?
+1
el777 #
Рубисты, у вас есть такая классная технология как Огурец. Расскажите, как она на практике. По описанию мне очень понравилось.
+2
snitko #
Субъективное мнение: на практике полезно, если в команде несколько человек и у вас есть клиент, для которого вы делаете проект и которому можно этот огурец показывать. В остальных случаях — сомнительный уровень абстракции.
+1
Astashov_Anton #
Ещё одно субъективное мнение — это круто только если вы пишете фичи вместе с заказчиком. Это настолько круто, насколько редко это бывает. :) А как по мне — обычные интеграционные тесты в связке с Webrat вполне себе хорошо заменяют Cucumber. И писанины намного меньше. И реюзабельности больше.
0
2kan #
По моему опыту их долго не удобно писать и невозможно поддерживать. Хотя во всех проектах, которых я работал интерфейс менялся часто и был обычно громоздкий.
0
Inpego #
Shoulda и Remarkable довольно похожи на первый взгляд, как вы выбирали? Хочу использовать что-нибудь из них.
0
akzhan #
Мы долгое вермя использовали Shoulda, а переход на Remarkable произошёл строго из-за его больше полноты (амтчерами покрыты все валидаторы AR, к примеру).

Да и писать свои матчеры под него приятнее.
0
Inpego #
Ясно, спасибо.

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