J'essaie de faire en sorte que mes tests se concentrent uniquement sur le contrat pour cette classe/module particulière. Si j'ai prouvé le comportement du module dans une classe de test pour ce module (généralement en incluant ce module dans une classe de test déclarée dans la spécification de ce module), je ne reproduirai pas ce test pour une classe de production qui utilise ce module. Mais s'il y a un comportement supplémentaire que je veux tester pour la classe de production, ou des problèmes d'intégration, j'écrirai des tests pour la classe de production.
Par exemple, j'ai un module appelé AttributeValidator
qui effectue des validations légères, similaires à celles de l'outil ActiveRecord
. J'écris des tests pour le comportement du module dans la spécification du module :
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
Maintenant, dans une classe de production qui inclut le module, je ne vais pas réaffirmer que les rappels sont effectués, mais je peux affirmer que la classe incluse a une certaine validation définie avec une certaine expression régulière, quelque chose de particulier à cette classe, mais qui ne reproduit pas les tests que j'ai écrits pour le module. Dans la spécification de la classe de production, je veux garantir que des validations particulières sont définies, mais pas que les validations fonctionnent en général. Il s'agit d'une sorte de test d'intégration, mais qui ne répète pas les mêmes assertions que celles que j'ai faites pour le module :
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
Il y a une certaine duplication ici (comme la plupart des tests d'intégration), mais les tests prouvent deux choses différentes pour moi. Un ensemble de tests prouve le comportement général du module, l'autre prouve les problèmes particuliers d'implémentation d'une classe de production qui utilise ce module. Grâce à ces tests, je sais que le module validera les attributs et effectuera des rappels, et je sais que ma classe de production possède un ensemble spécifique de validations pour des critères spécifiques propres à la classe de production.
J'espère que cela vous aidera.