JUnit 4.4+ has a feature called assumptions and I am looking for
something similar in rspec so that I can express that my examples
require a specific environment variable to be specified for testing to
make sense.
About assumptions from the readme (http://junit.sourceforge.net/doc/
ReleaseNotes4.4.html#assumptions):
"Ideally, the developer writing a test has control of all of the
forces that might cause a test to fail. If this isn’t immediately
possible, making dependencies explicit can often improve a design.
For example, if a test fails when run in a different locale than the
developer intended, it can be fixed by explicitly passing a locale to
the domain code.
However, sometimes this is not desirable or possible.
It’s good to be able to run a test against the code as it is currently
written, implicit assumptions and all, or to write a test that exposes
a known bug. For these situations, JUnit now includes the ability to
express “assumptions”:
"
/Morten
On Mon, Jun 1, 2009 at 5:33 AM, mortench [email protected] wrote:
JUnit 4.4+ has a feature called assumptions and I am looking for
something similar in rspec so that I can express that my examples
require a specific environment variable to be specified for testing to
make sense.
There is no explicit support for this, but you could always just say
(taking the example from the page you cited):
def assume_that(expression)
yield if expression
end
def verify_that(actual, expected)
actual.should expected
end
it “should blah de blah” do
assume_that(File::SEPARATOR == “/”) do
ensure_that User.new(“optimus”), eql(“configfiles/optimus.cfg”)
end
end
I am planning to add support for something like ensure_that (name up
for grabs) in a future version of rspec, but I’d need to think about
assume_that a bit. We’re dealing with Ruby here, not Java, and we
don’t suffer things like a ‘final’ keyword that force us to have to
make assumptions like this. Unless we add some additional feedback,
like “such and such example did not run due to faulty assumptions,”
this seems quite dangerous to me. And even with that, it means that CI
servers are going to pass examples that are never actually run.
HTH,
David
Hi David,
Thanks for the suggestion! It indeed make sense for the Junit
example… However, my particular usage case for assumption is a bit
different. I am using jruby+jspec and I have a group of rspec examples
that all require a java property to be set for the examples to be able
to run. Besides, the examples also have an after action that will also
break if the java propety is not set. Idealy, I would like to do
something like.
before(:all) do
@org_root_prop = java.lang.System.getProperty(“root”)
# abort all examples and after action if condition is not meet:
ensure_that !rootPath.nil? && rootPath.strip.length>0
end
Notice, that the assume is in a before action and not in the examples
themselves + it should affect the examples and after action (none of
which should run if before action assumptions are not meet).
/Morten
Correction for last msg:
before(:all) do
@org_root_prop = java.lang.System.getProperty(“root”)
# abort all examples and after action if condition is not meet:
ensure_that !@org_root_prop.nil? && @org_root_prop.strip.length>0
end
/Morten
I thought the point was we don’t want the examples to be run at all, if
the condition is not met? Though I’m wondering why not just handle
something like this with a stub (on System.getProperty in this case)?
Arthur S.
On Mon, Jun 1, 2009 at 7:26 AM, mortench [email protected] wrote:
Correction for last msg:
before(:all) do
@org_root_prop = java.lang.System.getProperty(“root”)
abort all examples and after action if condition is not meet:
ensure_that !@org_root_prop.nil? && @org_root_prop.strip.length>0
end
You could do this check outside of the example? ie:
describe “…” do
def self.ensure_that(condition, &blk)
yield if condition
end
def self.root_property_is_not_blank
org_root_prop = java.lang.System.getProperty(“root”)
org_root_prop.nil? && org_root_prop.strip.length>0
end
ensure_that root_property_is_not_blank do
it “…” do
end
end
end
/Morten
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users
–
Zach D.
http://www.continuousthinking.com (personal)
http://www.mutuallyhuman.com (hire me)
http://ideafoundry.info/behavior-driven-development (first rate BDD
training)
@zachdennis (twitter)
You can put expectations in your before block, and that’ll give you
the behavior you want.
before(:each) do
@org_root_prop = java.lang.System.getProperty(“root”)
@org_root_prop.should_not be_nil
@org_root_prop.trim.should_not be_empty
end
If either of those expectations fail then the examples that require
that property will report failures. If I were using this all over the
place, I would write a custom matcher.
before(:each) do
java.lang.System.should have_property(“root”)
@org_root_prop = java.lang.System.getProperty(“root”)
end
This would allow you to define your own error message and perform more
sophisticated expectations (see the have_tag/with_tag example in
rspec-rails).
Note that you should be doing this check in before(:each) because you
want it to run before each example. Also you should be using
before(:each) 99% of the time anyway.
Pat
Right, and in the code example I gave, if those preconditions fail
then the rest of the example won’t be run. There’s not really any
need for a new semantic element in RSpec, it already works this way
out of the box. You can do
it “should do something” do
some_precondition.should be_met
an_object.do_something
some_postcondition.should be_met
end
If the precondition is not met, the example fails and halts right there.
If you do want to visually distinguish them for some reason, you can
do so easily:
def assumptions
yield
end
it “should do something” do
assumptions do
some_precondition.should be_met
end
an_object.do_something
some_postcondition.should be_met
end
I personally wouldn’t but you could. I often use precondition
expectations in my examples. It helps me know where an error is more
quickly. I don’t waste time tracking down errors that result from
some precondition (assumption) being incorrect.
Pat
On Jun 1, 8:04 pm, Arthur S. [email protected] wrote:
I thought the point was we don’t want the examples to be run at all, if
the condition is not met?
Yes.
Though I’m wondering why not just handle
something like this with a stub (on System.getProperty in this case)?
Because the examples need the info in the property to work. The
property provides
reference values that the test use to compare against. Hence it makes
no sense to stub
anything out.
ALL: Thanks for all the help!
/Morten
On 1 Jun 2009, at 20:52, Pat M. wrote:
You can do
it “should do something” do
some_precondition.should be_met
an_object.do_something
some_postcondition.should be_met
end
Also, more verbosely…
describe “when there is some precondition”
before(:each) do
do_stuff_which_attempts_to_set_up_some_precondition
some_precondition.should be_met
end
it “should do something”
an_object.do_something
some_postcondition.should be_met
end
end
Which, can often make your specs read nicely. I also offers an obvious
space to think of a few more examples to throw in there.
cheers,
Matt