The promise of Shalt. 13
When writing requirements we often use the word “shall”. In Rspec, we use the word “should”. Some folks use the word “must”. These statements create the connotation of a law, or a command.
Let’s take a very old law: “Thou shalt not kill.” There are two ways to look at this law. We could look at it as a command[ment], or … we could look at it as a promise.
Here are the two different versions:
- Thou shalt not kill!
- Thou shalt not kill.
The difference is in the punctuation. And what a difference it makes. One is a stern order, a demand. The other is a promise… a confident guarantee… a statement of simple truth.
Now look at these rspec statements from RubySlim. I started writing the specs this way because it was shorter; but I like the connotation of confidence and truth. “I can has cheezburger.”
describe StatementExecutor do
before do
@caller = StatementExecutor.new
end
it "can create an instance" do
response = @caller.create("x", "TestModule::TestSlim",[])
response.should == "OK"
x = @caller.instance("x")
x.class.name.should == "TestModule::TestSlim"
end
it "can create an instance with arguments" do
response = @caller.create("x", "TestModule::TestSlimWithArguments", ["3"])
response.should == "OK"
x = @caller.instance("x")
x.arg.should == "3"
end
it "can't create an instance with the wrong number of arguments" do
result = @caller.create("x", "TestModule::TestSlim", ["noSuchArgument"])
result.should include(Statement::EXCEPTION_TAG + "message:<<COULD_NOT_INVOKE_CONSTRUCTOR TestModule::TestSlim[1]>>")
end
it "can't create an instance if there is no class" do
result = @caller.create("x", "TestModule::NoSuchClass", [])
result.should include(Statement::EXCEPTION_TAG + "message:<<COULD_NOT_INVOKE_CONSTRUCTOR TestModule::NoSuchClass failed to find in []>>")
end
end
This makes we want to change all the “should’ statement into “will” statement, or “does” statements.
One thing that I’m really trying to pursue more wholeheartedly is the documentation aspect of the output we get from running code examples.
Now that RSpec allows you to nest example groups and exposes #context as an alias for #describe, I might write what you wrote something like this:
Running this with the nested format option:
you’d get output like this:
Of course, once seeing that output, I realize that there is something missing from the description – the fact that #create works or fails because (at least in part) the number of arguments submitted matches the number of arguments expected. So I might see this and reorganize thusly:
Same examples, just renamed and reorganized – tells a more thorough and coherent story.
Not sure this addresses the dissonance you are observing between the example names and the code in the examples. I’ve toyed around with an alternate syntax that uses a function that interacts with rspec’s matchers a bit differently:
Not sure what the right name for the method is. Could be any of #expect_that, #specify_that, #verify_that, or even #assert_that.
In light of the guideline “specify, don’t verify” I think that #expect_that is probably the right one.
WDYT?
I used to use “should” in my specs, but after a while it begun looking like just some meaningless clutter. So nowadays I don’t use the “should” word in the spec names. (Also, I haven’t found any meaningful distinction between “should” and “must”.)
Instead of writing “the ball should be round” I prefer writing “the ball is round”.
I never liked “should” much myself. On the other hand, let’s rephrase the distinction slightly, saying that “should” states a requirement and “does” expresses a fact. Now we can see that “should” more clearly indicates that it precedes the implementation. For those of us who have been working test-first for years, that might be an unnecessary reminder, but I can see how it might be considered useful for the unwashed masses ;-)
I always thought that “should” was a bit non-committal, but backed off after being called a fascist (or something like that) on a mailing list. I think Chris Stevenson got it right with his TestDox approach all those years ago.
Steve – fascist? Ouch! I hope that wasn’t on the rspec list. And I especially hope it wasn’t me!
I really dislike the words “shall”, “should”, “will” or “would” in specs of any kind.
I think that specs should be written as if the system behaves a certain way at any given instance in time. That way the spec “magically” turns into an (potentially testable) assertion and documentation.
I used to have to read requirements docs full of “The system shall…” repeated over and over again. I would do a search and replace on my copy of the Doc file just to get rid of the phrase to make things more readable.
Thanks for sharing these info with us! I was reading something similar on another website that i was researching. I will be sure to look around more. thanks…
The other is a promise… a confident guarantee… a statement of simple truth.
I am looking a way to solve it. I want to study. When I come to here, I think I am in the right place. the web gives me a lot of infomation, it is very informative.
Not sure this addresses the dissonance you are observing between the example names and the code in the examples. I’ve toyed around with an alternate syntax that uses a function that interacts with rspec’s matchers a bit differently.
great code.
Dunyanin en büyük online okey oyunu bu sitede sizleri bekliyor. Gerçek kisilerle sohbet ederek okey oyunu oyna ve internette online oyun oynamanin zevkini çikar.
LOLZ
“The other is a promise… a confident guarantee… a statement of simple truth.”
Agreed
The code is not working for me. Any other solution?