I'm struggling with Test::Unit. When I think of unit tests, I think of one simple test per file. But in Ruby's framework, I must instead write:
class MyTest < Test::Unit::TestCase
def setup
end
def test_1
end
def test_1
end
end
But setup and teardown run for every invocation of a test_* method. This is exactly what I don't want. Rather, I want a setup method that runs just once for the whole class. But I can't seem to write my own initialize() without breaking TestCase's initialize.
Is that possible? Or am I making this hopelessly complicated?
As mentioned in Hal Fulton's book "The Ruby Way". He overrides the self.suite method of Test::Unit which allows the test cases in a class to run as a suite.
Here is an example:
I created a mixin called SetupOnce. Here's an example of using it.
And here is the actual code; notice it requires another module available from the first link in the footnotes.
Footnotes:
http://redcorundum.blogspot.com/2006/06/mixing-in-class-methods.html
http://infovore.org/archives/2006/08/02/getting-a-class-object-in-ruby-from-a-string-containing-that-classes-name/
I came across this exact problem and created a subclass of
Test::Unit::TestCase
for doing exactly what you describe.Here's what I came up with. It provides it's own
setup
andteardown
methods that count the number of methods in the class that begin with 'test'. On the first call tosetup
it callsglobal_setup
and on the last call toteardown
it callsglobal_teardown
Create your test cases like this:
The fault in this is that you can't provide your own per-test
setup
andteardown
methods unless you use thesetup :method_name
class method (only available in Rails 2.X?) and if you have a test suite or something that only runs one of the test methods, then theglobal_teardown
won't be called because it assumes that all the test methods will be run eventually.I know this is quite an old post, but I had the issue (and had already written classes using Tes/unit) and ave answered using another method, so if it can help...
If you only need the equivalent of the startup function, you can use the class variables:
FINALLY, test-unit has this implemented! Woot! If you are using v 2.5.2 or later, you can just use this:
This will run once when you start your tests off. There are also callbacks which run at the beginning of each test case (startup), in addition to the ones that run before every test (setup).
http://test-unit.rubyforge.org/test-unit/en/Test/Unit.html#at_start-class_method
Well, I accomplished basically the same way in a really ugly and horrible fashion, but it was quicker. :) Once I realized that the tests are run alphabetically:
It aint pretty, but it works :)