>Comment By: Luis Lavena (luislavena) > Date: 2007-05-04 23:37> describe "An Asset" do > before(:each) do > @asset = Asset.new > end > > it { @asset.should have_one(:attachment) } > it { @asset.should have_present(:something) } > endFood for thought on these. I like have_one a lot. It speaks to me as a Rails developer and I think it speaks to a customer as well. On the flip side, ''have_present'' doesn''t really tell me what is interesting about having it present, or why it should be present. I think ''require_attribute'' would be nice (''require'' would be even better, but obviously that is a keyword). Or ''validate_presence_of'': an { @asset.should validate_presence_of(:something) } That''s a little more Rails-developer-friendly than customer-friendly, but it still ''speaks'' better than ''have_present'' for me. FYI - Jay Fields has a Validatable framework that includes some test/unit assertions that look like this: Foo.must_validate do presence_of :name format_of(:name).with(/^[A-Z]/) numericality_of(:age).only_integer(true) end Because Spec::Rails behaviours inherit from Test::Unit::TestCase, you can install the validations gem (gem install validatable) and use these as/is with RSpec. Or, if you want it to feel more spec''ish, you could monkey patch an alias: Foo.should_validate do presence_of :name format_of(:name).with(/^[A-Z]/) numericality_of(:age).only_integer(true) end Whether you choose to use his framework or write your own, I think there is something to be learned from its expressiveness. Cheers, David
On 5/4/07, David Chelimsky <dchelimsky at gmail.com> wrote:> >Comment By: Luis Lavena (luislavena) > > Date: 2007-05-04 23:37 > > > describe "An Asset" do > > before(:each) do > > @asset = Asset.new > > end > > > > it { @asset.should have_one(:attachment) } > > it { @asset.should have_present(:something) } > > end > > Food for thought on these. I like have_one a lot. It speaks to me as a > Rails developer and I think it speaks to a customer as well. > > On the flip side, ''have_present'' doesn''t really tell me what is > interesting about having it present, or why it should be present. I > think ''require_attribute'' would be nice (''require'' would be even > better, but obviously that is a keyword). Or ''validate_presence_of'': > > an { @asset.should validate_presence_of(:something) } > > That''s a little more Rails-developer-friendly than customer-friendly, > but it still ''speaks'' better than ''have_present'' for me. > > FYI - Jay Fields has a Validatable framework that includes some > test/unit assertions that look like this: > > Foo.must_validate do > presence_of :name > format_of(:name).with(/^[A-Z]/) > numericality_of(:age).only_integer(true) > end > > Because Spec::Rails behaviours inherit from Test::Unit::TestCase, you > can install the validations gem (gem install validatable) and use > these as/is with RSpec. Or, if you want it to feel more spec''ish, you > could monkey patch an alias: > > Foo.should_validate do > presence_of :name > format_of(:name).with(/^[A-Z]/) > numericality_of(:age).only_integer(true) > endD''oh!! Foo.should validate do ...> Whether you choose to use his framework or write your own, I think > there is something to be learned from its expressiveness. > > Cheers, > David >
On 5/5/07, David Chelimsky <dchelimsky at gmail.com> wrote:> >Comment By: Luis Lavena (luislavena) > > Date: 2007-05-04 23:37 > > > describe "An Asset" do > > before(:each) do > > @asset = Asset.new > > end > > > > it { @asset.should have_one(:attachment) } > > it { @asset.should have_present(:something) } > > end > > Food for thought on these. I like have_one a lot. It speaks to me as a > Rails developer and I think it speaks to a customer as well. > > On the flip side, ''have_present'' doesn''t really tell me what is > interesting about having it present, or why it should be present. I > think ''require_attribute'' would be nice (''require'' would be even > better, but obviously that is a keyword). Or ''validate_presence_of'': > > an { @asset.should validate_presence_of(:something) } > > That''s a little more Rails-developer-friendly than customer-friendly, > but it still ''speaks'' better than ''have_present'' for me. >yeah, have_present was due "require" been reserved word :-P validate_presence_of was another option, but that will force me to use validate_uniqueness_of, etc... A lot of typing just for one liner of example :-P> FYI - Jay Fields has a Validatable framework that includes some > test/unit assertions that look like this: > > Foo.must_validate do > presence_of :name > format_of(:name).with(/^[A-Z]/) > numericality_of(:age).only_integer(true) > end > > Because Spec::Rails behaviours inherit from Test::Unit::TestCase, you > can install the validations gem (gem install validatable) and use > these as/is with RSpec. Or, if you want it to feel more spec''ish, you > could monkey patch an alias: >I wasn''t aware of it, thanks for the tip.> Foo.should_validate do > presence_of :name > format_of(:name).with(/^[A-Z]/) > numericality_of(:age).only_integer(true) > end > > Whether you choose to use his framework or write your own, I think > there is something to be learned from its expressiveness. >Of course, I often try to keep small the set of plugins/gems I use during development, which require I do gem install there to get the functionality. Piston the gem just for testing is also questionable, but doable.> Cheers, > DavidAgain, thank for your your feedback, Regards, -- Luis Lavena Multimedia systems - Leaders are made, they are not born. They are made by hard effort, which is the price which all of us must pay to achieve any goal that is worthwhile. Vince Lombardi
On 5/4/07, Luis Lavena <luislavena at gmail.com> wrote:> On 5/5/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > >Comment By: Luis Lavena (luislavena) > > > Date: 2007-05-04 23:37 > > > > > describe "An Asset" do > > > before(:each) do > > > @asset = Asset.new > > > end > > > > > > it { @asset.should have_one(:attachment) } > > > it { @asset.should have_present(:something) } > > > end > > > > Food for thought on these. I like have_one a lot. It speaks to me as a > > Rails developer and I think it speaks to a customer as well. > > > > On the flip side, ''have_present'' doesn''t really tell me what is > > interesting about having it present, or why it should be present. I > > think ''require_attribute'' would be nice (''require'' would be even > > better, but obviously that is a keyword). Or ''validate_presence_of'': > > > > an { @asset.should validate_presence_of(:something) } > > > > That''s a little more Rails-developer-friendly than customer-friendly, > > but it still ''speaks'' better than ''have_present'' for me. > > > > yeah, have_present was due "require" been reserved word :-P > > validate_presence_of was another option, but that will force me to use > validate_uniqueness_of, etc... > > A lot of typing just for one liner of example :-PFWIW, you only have to type these things once each time you type them. You''re going to read them hundreds of times. It''s worth the extra typing in my view! If the examples are documentation, they should tell you, with as little mental mapping as possible, what it is that''s being described. Using ''validate_presence_of'' tells me EXACTLY what the code should look like. That''s worth a lot to me. Cheers, David> > > FYI - Jay Fields has a Validatable framework that includes some > > test/unit assertions that look like this: > > > > Foo.must_validate do > > presence_of :name > > format_of(:name).with(/^[A-Z]/) > > numericality_of(:age).only_integer(true) > > end > > > > Because Spec::Rails behaviours inherit from Test::Unit::TestCase, you > > can install the validations gem (gem install validatable) and use > > these as/is with RSpec. Or, if you want it to feel more spec''ish, you > > could monkey patch an alias: > > > > I wasn''t aware of it, thanks for the tip. > > > Foo.should_validate do > > presence_of :name > > format_of(:name).with(/^[A-Z]/) > > numericality_of(:age).only_integer(true) > > end > > > > Whether you choose to use his framework or write your own, I think > > there is something to be learned from its expressiveness. > > > > Of course, I often try to keep small the set of plugins/gems I use > during development, which require I do gem install there to get the > functionality. > > Piston the gem just for testing is also questionable, but doable. > > > Cheers, > > David > > Again, thank for your your feedback, > > Regards, > > -- > Luis Lavena > Multimedia systems > - > Leaders are made, they are not born. They are made by hard effort, > which is the price which all of us must pay to achieve any goal that > is worthwhile. > Vince Lombardi > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 5/5/07, David Chelimsky <dchelimsky at gmail.com> wrote: [...]> > yeah, have_present was due "require" been reserved word :-P > > > > validate_presence_of was another option, but that will force me to use > > validate_uniqueness_of, etc... > > > > A lot of typing just for one liner of example :-P > > FWIW, you only have to type these things once each time you type them. > You''re going to read them hundreds of times. It''s worth the extra > typing in my view! If the examples are documentation, they should tell > you, with as little mental mapping as possible, what it is that''s > being described. Using ''validate_presence_of'' tells me EXACTLY what > the code should look like. That''s worth a lot to me. >Valid point, Prior matchers I was using eval to create the specifys... should_validate_presence_of, uniqueness_of, etc. I tried to make shorter, but descriptives versions since upgrade. # Here start the accessor for examples: # it { @model.should have_present(:attr) } => should not be valid without :attr # it { @model.should have_unique(:attr) } => should not be valid with duplicate :attr # it { @model.should have_one(:attr, :through => :assoc) } => should has_one :attr through :assoc # it { @model.should belongs_to(:attr, :through => :assoc) } => should belongs_to :attr through :assoc # it { @model.should have_many(:attr, :through => :assoc) } => should has_many :attr through :assoc # it { @model.should have_and_belongs_to_many(:attr, :through => :assoc) } => should has_and_belongs_to_many :attr through :assoc # it { @model.should have_no_errors } => should have no errors Suggestions are welcome ;-) -- Luis Lavena Multimedia systems - Leaders are made, they are not born. They are made by hard effort, which is the price which all of us must pay to achieve any goal that is worthwhile. Vince Lombardi
On 5/4/07, David Chelimsky <dchelimsky at gmail.com> wrote:> FYI - Jay Fields has a Validatable framework that includes some > test/unit assertions that look like this: > > Foo.must_validate do > presence_of :name > format_of(:name).with(/^[A-Z]/) > numericality_of(:age).only_integer(true) > end...> Whether you choose to use his framework or write your own, I think > there is something to be learned from its expressiveness.Something doesn''t sit right with me for both Jay Field''s test validations and also http://spicycode.com/2007/4/2/rspec-expecation-matchers-part-ii To me, it feels like both of them are testing the implementation too closely, rather than checking the expected behavior. I think that this problem is best exhibited by format_of. What am I verifying? That the production code contains the exact same regex as my spec code? That seems a bit silly to me, when the regex itself is the item that should be tested most! It''s what is carrying the behavior. And, while the simple "first character should be a capital letter" may seem like a silly one to worry about, what about a more complicated regex, such as an email address validation? I would seriously distrust any spec containing a complicated regex which is attempting to validate another complicated regex. What I''d *really* like is something a lot simpler (even if more verbose), that focuses entirely on examples and the behavior exhibited for those examples. Basically, I want to give a set of invalid examples, and verify that they are indeed invalid, as well as some valid examples, and verify that they pass validation. But I''m still having a hard time coming up with a nice syntax for this. I was having a discussion with a coworker about this earlier in the week, and I pastied my first thoughts about this here: http://pastie.caboo.se/58438 After resting on it a bit, I also came up with another syntax, pastied here: http://pastie.caboo.se/59162 I''ll readily admit that Jay Field''s DSL looks much nicer than what I''ve come up with so far... but I''d rather stick with the plain vanilla rspec, and be certain that I''m asserting an expected model behavior against examples than expect the implementation details of which ActiveRecord validation was used. Am I just making things harder for myself? Am I missing the boat on a useful simplification? -- Nick
On 5/5/07, nicholas a. evans <nick at ekenosen.net> wrote:> ... > > Something doesn''t sit right with me for both Jay Field''s test > validations and also > http://spicycode.com/2007/4/2/rspec-expecation-matchers-part-ii > > To me, it feels like both of them are testing the implementation too > closely, rather than checking the expected behavior. I think that > this problem is best exhibited by format_of. What am I verifying? > That the production code contains the exact same regex as my spec > code? That seems a bit silly to me, when the regex itself is the item > that should be tested most! It''s what is carrying the behavior. And, > while the simple "first character should be a capital letter" may seem > like a silly one to worry about, what about a more complicated regex, > such as an email address validation? I would seriously distrust any > spec containing a complicated regex which is attempting to validate > another complicated regex. >Nick, most of the validations I do about presence of a field, uniqueness of a field, or even the associations are based (and most of them) translated from requirements customer shared with me. I needed to find a way to show them I''m following they rules, their requirements, but also be useful for me.> What I''d *really* like is something a lot simpler (even if more > verbose), that focuses entirely on examples and the behavior exhibited > for those examples. Basically, I want to give a set of invalid > examples, and verify that they are indeed invalid, as well as some > valid examples, and verify that they pass validation. > > But I''m still having a hard time coming up with a nice syntax for > this. I was having a discussion with a coworker about this earlier in > the week, and I pastied my first thoughts about this here: > http://pastie.caboo.se/58438 After resting on it a bit, I also came > up with another syntax, pastied here: http://pastie.caboo.se/59162 >Both pasties looks interesting, since you''re testing for valid and invalid values, something I disregard on my matchers. To not generate false possitives, I''ve should validte them and later provide a valid value instead... will stick that in my TODO list.> I''ll readily admit that Jay Field''s DSL looks much nicer than what > I''ve come up with so far... but I''d rather stick with the plain > vanilla rspec, and be certain that I''m asserting an expected model > behavior against examples than expect the implementation details of > which ActiveRecord validation was used. > > Am I just making things harder for myself? Am I missing the boat on a > useful simplification?My idea of specs (er, examples) are useful for me and my customer during the first design/implementation phase, but uses for rspec are too broad ;-) Regards and good weekend everyone. -- Luis Lavena Multimedia systems - Leaders are made, they are not born. They are made by hard effort, which is the price which all of us must pay to achieve any goal that is worthwhile. Vince Lombardi
On 5/5/07, nicholas a. evans <nick at ekenosen.net> wrote:> On 5/4/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > FYI - Jay Fields has a Validatable framework that includes some > > test/unit assertions that look like this: > > > > Foo.must_validate do > > presence_of :name > > format_of(:name).with(/^[A-Z]/) > > numericality_of(:age).only_integer(true) > > end > ... > > Whether you choose to use his framework or write your own, I think > > there is something to be learned from its expressiveness. > > Something doesn''t sit right with me for both Jay Field''s test > validations and also > http://spicycode.com/2007/4/2/rspec-expecation-matchers-part-ii > > To me, it feels like both of them are testing the implementation too > closely, rather than checking the expected behavior. I think that > this problem is best exhibited by format_of. What am I verifying? > That the production code contains the exact same regex as my spec > code? That seems a bit silly to me, when the regex itself is the item > that should be tested most! It''s what is carrying the behavior. And, > while the simple "first character should be a capital letter" may seem > like a silly one to worry about, what about a more complicated regex, > such as an email address validation? I would seriously distrust any > spec containing a complicated regex which is attempting to validate > another complicated regex. > > What I''d *really* like is something a lot simpler (even if more > verbose), that focuses entirely on examples and the behavior exhibited > for those examples. Basically, I want to give a set of invalid > examples, and verify that they are indeed invalid, as well as some > valid examples, and verify that they pass validation. > > But I''m still having a hard time coming up with a nice syntax for > this. I was having a discussion with a coworker about this earlier in > the week, and I pastied my first thoughts about this here: > http://pastie.caboo.se/58438 After resting on it a bit, I also came > up with another syntax, pastied here: http://pastie.caboo.se/59162 > > I''ll readily admit that Jay Field''s DSL looks much nicer than what > I''ve come up with so far... but I''d rather stick with the plain > vanilla rspec, and be certain that I''m asserting an expected model > behavior against examples than expect the implementation details of > which ActiveRecord validation was used. > > Am I just making things harder for myself? Am I missing the boat on a > useful simplification?This is a very gray area. I can see arguments for Jay''s approach and for the approach you''re going for as well. The trick is to not get up in the dogma of any given approach and understand why it might or might not be valuable, and in what situations. Why do we care about avoiding implementation details in tests? Because they make tests brittle. Why? Because implementations tend to change more than interfaces. What about our model implementation might change? Are we going to possibly change from ActiveRecord::Base to some other persistence framework? Assuming very low likelihood that we''ll decouple our Rails apps from AR, then I think it''s OK to do these simpler but more implementation focused tests. They cover a LOT of ground in a very clear way. Here''s another way to look at it. There is a rule of thumb in TDD that says "test YOUR code, not somebody else''s." The idea is that when you''re using someone else''s API, you should hide it behind an adapter that is catered to the needs of your application. In tests of your code, you specify that they should use the wrapper correctly using mock implementations of the wrapper. Then you have a small suite of tests that verifies that your wrapper interacts correctly w/ the 3rd partly API. This allows you great flexibility in switching to a different API. In that case, nobody would blink an eye if you used the mocks to specify that your model interacts correctly with the adapter. Accepting that approach, then what is the difference, really, between that and Jay''s approach, which essentially mocks AR and lets you specify that your model class interacts with it correctly?
On 5/5/07, David Chelimsky <dchelimsky at gmail.com> wrote:> This is a very gray area.Agreed. ;-)> Why do we care about avoiding implementation details in tests? > Because they make tests brittle.I think that there is another reason, which is sometimes more important (and sometimes less): doing this communicates the actual system requirements better than do implementation details.> Are we going to possibly change from ActiveRecord::Base to > some other persistence framework?No. However, just for the sake of argument, I will bring up that I have recently had to change my persistence framework from ActiveRecord::Base (version 1.1.6) to ActiveRecord::Base (version 1.2.2). Various other incompatibilities (largely brought on ourselves by working too closely with private APIs) are still fresh in my mind. But I agree with your point here; the core validations aren''t likely to be changing much from one version of AR::Base to the next.> They cover a LOT of ground in a very clear way.I still have misgivings about just how clear it actually is.> Here''s another way to look at it. There is a rule of thumb in TDD that > says "test YOUR code, not somebody else''s."...> Accepting that approach, then what is the difference, really, between > that and Jay''s approach, which essentially mocks AR and lets you > specify that your model class interacts with it correctly?I usually come down rather heavily in the "isolation test with all dependencies mocked out" camp. I''m really not sure how to consistently resolve my double standard here. I simply feel very uneasy using mock expectations for model validations. on readability: Granted, "validates_presence_of" is incredibly simple and easy for anyone to understand and validates_numericality_of and validates_confirmation_of may speak to us as rails programmers, but do they speak to our BAs and PMs? "Numericality" isn''t even an english word! :-) Wouldn''t it be much simpler and far more communicative if we said, "when the object''s attributes are set to these values, the object is marked as invalid, can''t be saved, and has this error message"? From a business user''s perspective, isn''t that what they really care about? on changing the implementation after the fact (and brittle tests): I think that most apps don''t need to use much beyond the basic rails-provided validations, so this approach probably works better for them than for my company. But my apps have relatively few validates_presence_of, compared to a large number of state based (or other complicated) validations (when this attribute is set to such and such, or when the model is in such and such a state, then these other conditions must be valid"). When we do use the standard rails validations, we often also pass in an :if or :unless block. The further you stray from the simple use case of just adding the validation to the model with no extra parameters, the more it looks like you are just copying and pasting code from your specs into your production code. (Unless you aren''t working TDD/BDD, in which case the copying goes in the opposite direction!) If you were to use valid/invalid examples, then you wouldn''t need to change each example every time you add another condition to your validations... you would simply add/modify/remove the examples that make sense. I would argue that this makes more sense from a TDD/BDD perspective, as well as from a "brittle tests" perspective. on meaningful specs: validates_format_of (or other similarly complicated validations, such as using :if or :unless) is really where I have my biggest problem. Ignore all of the above as an misguided ideological rant, and I''ll be completely fine with that. In time, I might even agree with you. ;-) But what does the following mean: model.should validate_format_of(:email, /\w+@\w+\.\w+/) oh, that was rather naive, it isn''t catching "foo bar blatz at test.com" as invalid. Okay, let''s change the code and the spec: model.should validate_format_of(:email, /^\w+@\w+\.\w+$/) oh, now we have one of my pet peeves, "foo+bar at test.com" isn''t considered valid, nor is "foo at test.domain.com". "foo_bar at test.com" is still valid, but "foo-bar at test.com" is not. Do you see my point? These are very simple regular expressions, but they are already non-trivial and less obvious to read than what they are able accomplish. Sure, I could go onto the net and borrow someone else''s pre-built email regex validation... but that only helps with email addresses. What about some other complicated problem more in your specific domain? What about a problem that you originally *thought* you could solve with a regex, but you later found something that a regex couldn''t handle or you found a more performant or a simpler implementation. That we are calling "validates_format_of" with a specific regular expression has almost *nothing* to do with our requirements. That we consider certain classes of strings to be valid and certain to be invalid, *that* is what matters. My fear is that by adopting this style of validations, we make things a little bit more concise where we need it the least (with the very very simple validations), but encourage a style that will be detrimental for the even the mildly complicated validations. Here''s another attempt at a syntax that is hopefully simple and readable: valid_model.should validate(:with_message => "Unacceptable email address.") do valid :email => "foo at bar.com" valid :email => "foo+extension at bar.com" valid :email => "foo-bar at test.com" valid :email => "foo-bar at test.domain.com" invalid :email => "no spaces please foo at bar.com" invalid :email => "@no.username.com" invalid :email => "only_tld at com" invalid({:email => ""}, :with_message => "Should provide email address") valid :email => "", :status => "registration incomplete" valid :email => "", :user_role => "fake" valid :email => "", :user_role => "admin" end Keeping in mind, of course, that real business rules tend to be even crazier than a simple email address validation. I''m not even saying that all of the above rules above make sense, but that doesn''t mean that rules of that level of complexity won''t be demanded by our customers. ;-) I think that the above style communicates much more clearly than: model.should validate_format_of(cryptic_regex).with(:option1 => "blahblahblah", :option2 => "blahblahblah") But again, I might be tilting at windmills, so I''m looking for some validation of my thoughts. ;-) (pun unfortunately intended) -- Nick
On 5/7/07, nicholas a. evans <nick at ekenosen.net> wrote:> validates_format_of (or other similarly complicated validations, such > as using :if or :unless) is really where I have my biggest problem.Sorry that my last email was such a long rant. I''ll try to restate the important part more clearly, so you can ignore the other email. ;-) As an example, let''s try BDD with email address validation. We''ll start with something simple like: model.should validate_format_of(:email, /\w+@\w+\.\w+/) and then add this to the model, to make the spec pass: validate_format_of :email, :with => /\w+@\w+\.\w+/ Oh, that was rather naive; "foo bar blatz at test.com" is still valid. Okay then, that old spec line was wrong; let''s change it to: model.should validate_format_of(:email, /^\w+@\w+\.\w+$/) and then change the model to: validate_format_of :email, :with => /^\w+@\w+\.\w+$/ Strange, this feels like I''m copying and pasting from my spec to my code! Unfortunately, "foo+bar at test.com" isn''t considered valid, nor is "foo at test.domain.com". "foo_bar at test.com" is still valid, but "foo-bar at test.com" is not. And so on, ad-infinitum, except that the specs provide no fall-back guarantee that something that used to work will still work, because I''m completely rewriting the spec at each step along the way. This testing style feels rather brittle, and I''m still only using ActiveRecord. At some point, I think that I''d give up on TDD/BDD, and just write the code first, then copy it back to the validation spec. So, what happens when I want to say this? validate_format_of :with => cryptic_email_regex, :unless => lambda { |user| user.type == "local" } These are very simple regular expressions, and very simple business rules, but they are already non-trivial and nuanced enough that the validation method that is called is unimportant, and simple examples of what is valid or invalid are far less confusing than a cryptic but powerful regex. What I prefer to do: first I would add a simple example of a valid value, and make sure that works prior to having any validations in place. Then I''d add a simple example of an invalid value, run the code, see that it fails, then add the simplest validation necessary to pass the specs. Then I''d add another example, see it fail, and make it work. I''d look closely at my implementation to see if there are any edge-cases and then I''d make examples of them to see if any of them fail, and I''d make them work. And so on. When the business requirements change, most likely I''ll not need to change any examples, I''ll just need to add another. At the end, I might wind up with something similar to the following (another validation DSL attempt): valid_model.should validate(:with_message => "Unacceptable email address.") do valid :email => "foo at bar.com" valid :email => "foo+extension at bar.com" valid :email => "foo-bar at test.com" valid :email => "foo-bar at test.domain.com" invalid :email => "anything at domain.we.dont.like" invalid :email => "no spaces please foo at bar.com" invalid :email => "@no.username.com" invalid :email => "only_tld at com" invalid({:email => ""}, :with_message => "Should provide email address") valid :email => "", :status => "registration incomplete" valid :email => "", :user_role => "fake" valid :email => "", :user_role => "admin" valid :email => "username", :type => "local" valid :email => "username at local.domain", :type => "local" invalid({:email => "username at domain.com", :type => "local"}, :with_message => "local users must use a local username") end Please ignore whether or not the above validations are reasonable. My imaginary business analyst tells me they are all very important. The level of complexity should be reasonable, despite my bad examples. :-) This style feels much more compatible with TDD/BDD, and far less brittle. I also think that it is much clearer and more communicative. It just isn''t as concise. But then again, it might be clear from my rambling emails that I don''t place enough value on being concise. ;-) -- Nick
I have to agree, Nick. Specs should be about behaviour and not implementation, though the two will inevitably overlap. Even specifying associations (another recent discussion) might be too much - what the client is really interested in is the behaviour associations offer (or rather the problem-specific solutions that behaviour allows you to offer). So long as one regards such a spec as being shorthand for the end behaviour there should be no problem, but if we are too specific in our specifications we might end up dictating implementation choices which are neither necessary nor, perhaps desirable. I like your valid/invalid syntax too. Best wishes, Jerry PS: "Independent" confirmation of an implementation detail (''did I type it right?'') can be very helpful and I know I have used tests & specs for exactly that purpose, but in my case I suspect it''s really a lack of confidence in my own abilities and understanding! Is it really the role of a spec to double check that the coder has typed the right thing?