Specs are a mess
-
bahuvrihi
- State changed from new to open
- Assigned user set to bahuvrihi
(from [d866af0862875abc014428dcd8c60832bd6da137]) cleanup of specs, removing spurious includes and reworking descriptions [#1 Specs are a mess responsible:bahuvrihi state:open] http://github.com/bahuvrihi/ms-m...
-
bahuvrihi
A downside of this system is that it silently allows duplicate definition of methods:
class SampleSpec < MiniTest::Spec it "must flunk" { flunk } it "must flunk" { pass } endThis will pass and it will not notify that the first 'must flunk' is overridden. It would be better if we could wrap each method spec in a describe statement like:
describe "Sample#class_method" do it "must/should do this" {} end describe "Sample.instance_method" do it "must/should do that" {} endBut again, this comes with the include problem. Again, an alternative to using the traditional class definition and include is to use describe and full constant names.
describe "SampleSpec" do it "uses a full constant name" do What::Needs::Including end end -
bahuvrihi
I've submitted a ticket to MiniTest to raise a warning when methods get duplicated, so hopefully this won't be an issue in the future.
-
jtprince
The solutions proposed are sound. Still, I think as described they reflect more of a unit test style (which is a good thing) but are not as compatible with more of a behavior/spec style.
I'm thinking the above style testing should be included in some sort of "unit" spec. (Of course, since specs are supersets of tests, one could always just write unit tests as before...)
class SampleUnitTest < MiniTest::Spec include What::Needs::Including # # describe Sample#class_method # it "must/should do this" {} # # describe Sample.instance_method # it "must/should do that" {} endIn general, I prefer a more direct statement in 'it' methods:
# I like this: it 'does this' {} # over this: it 'must do this' {} # because the first is more DRY (the 'must' is implied in a spec).This kind of a unit test/spec is handy for development and to ensure proper behavior from each method.
A spec is tied much less closely to the implementation and more to one particular context and expected behaviors:
class SampleWithSuperSampleFile < MiniTest::Spec # # describe Sample given a SuperSample file # before do @obj = SuperSample.read(file) end it 'tells how big the file is' do obj.size.must_equal 7 end it 'spits out xml for each section' do obj.each_section do |section| section.to_xml.must_equal precached_xml end end endI think it is natural to order these by most critical behavior. The implementation is of secondary importance to what the thing actually does in a certain context. In any case, whatever implementation you choose to accomplish the behavior, the spec is self-documenting. One glance inside the spec tells a person how to do the behavior. With this style, it makes much less sense tie a test method (i.e., the 'it') to a single method. Sometimes, to accomplish the required behavior will take a few different method calls... upper level behavior may span different classes entirely.
-
bahuvrihi
Really good points. Maybe it's a matter of applying a spec/test style to the right problem? I can see how high level behavior is nicely supported by specs that don't say much of anything of how a thing is implemented, and for low-level things (where you're wondering if this single method actually works) an orderly test style might suit.
# I like this: it 'does this' {} # over this: it 'must do this' {} # because the first is more DRY (the 'must' is implied in a spec).I see what you're talking about here too. English teachers would applaud the active tense... the 'must/should' sounds to me more like a test-style spec while the 'does' is more descriptive of behavior.
-
bahuvrihi
- State changed from open to resolved
Please Sign in or create a free account to add a new ticket.
With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.