Я стараюсь сосредоточить свои тесты только на контракте для этого конкретного класса / модуля. Если я докажу поведение модуля в тестовом классе для этого модуля (обычно путем включения этого модуля в тестовый класс, объявленный в спецификации для этого модуля), то я не буду дублировать этот тест для производственного класса, который использует этот модуль. Но если я хочу проверить дополнительное поведение для производственного класса или проблемы интеграции, я напишу тесты для производственного класса.
Например, у меня есть модуль с именем AttributeValidator
, который выполняет легкие проверки, похожие на ActiveRecord
. Я пишу тесты для поведения модуля в спецификации модуля:
before(:each) do
@attribute_validator = TestAttributeValidator.new
end
describe "after set callbacks" do
it "should be invoked when an attribute is set" do
def @attribute_validator.after_set_attribute_one; end
@attribute_validator.should_receive(:after_set_attribute_one).once
@attribute_validator.attribute_one = "asdf"
end
end
class TestAttributeValidator
include AttributeValidator
validating_str_accessor [:attribute_one, /\d{2,5}/]
end
Теперь в производственном классе, который включает модуль, я не буду вновь утверждать, что обратные вызовы сделаны, но я могу утверждать, что у включенного класса есть определенный набор проверки с определенным регулярным выражением, что-то особенное для этого класса , но не воспроизводит тесты, которые я написал для модуля. В спецификации для производственного класса я хочу гарантировать, что установлены определенные валидации, но не то, что валидации работают в целом. Это своего рода интеграционный тест, но он не повторяет те же утверждения, которые я сделал для модуля:
describe "ProductionClass validation" do
it "should return true if the attribute is valid" do
@production_class.attribute = @valid_attribute
@production_class.is_valid?.should be_true
end
it "should return false if the attribute is invalid" do
@production_class.attribute = @invalid_attribute
@production_class.is valid?.should be_false
end
end
Здесь есть некоторое дублирование (как и в большинстве интеграционных тестов), но тесты доказывают мне две разные вещи. Один набор тестов подтверждает общее поведение модуля, другой - конкретные проблемы реализации производственного класса, использующего этот модуль. Из этих тестов я знаю, что модуль будет проверять атрибуты и выполнять обратные вызовы, и я знаю, что мой производственный класс имеет определенный набор проверок для конкретных критериев, уникальных для производственного класса.
Надеюсь, это поможет.