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?
+1 for the RSpec answer above by @orion-edwards. I would have commented on his answer, but I don't have enough reputation yet to comment on answers.
I use test/unit and RSpec a lot and I have to say ... the code that everyone has been posting is missing a very important feature of
before(:all)
which is: @instance variable support.In RSpec, you can do:
The implementations of
#startup
and#shutdown
above all focus on making sure that these methods only get called once for the entireTestCase
class, but any instance variables used in these methods would be lost!RSpec runs its
before(:all)
in its own instance of Object and all of the local variables are copied before each test is run.To access any variables that are created during a global
#startup
method, you would need to either:#startup
, like RSpec does#startup
into a scope that you can access from your test methods, eg.@@class_variables
or create class-level attr_accessors that provide access to the@instance_variables
that you create inside ofdef self.startup
Just my $0.02!
To solve this problem I used the setup construct, with only one test method followed. This one testmethod is calling all other tests.
For instance
That's how it's supposed to work!
Each test should be completely isolated from the rest, so the
setup
andtear_down
methods are executed once for every test-case. There are cases, however, when you might want more control over the execution flow. Then you can group the test-cases in suites.In your case you could write something like the following:
The
TestDecorator
defines a special suite which provides asetup
andtear_down
method which run only once before and after the running of the set of test-cases it contains.The drawback of this is that you need to tell Test::Unit how to run the tests in the unit. In the event your unit contains many test-cases and you need a decorator for only one of them you'll need something like this:
The Test::Unit documentation documentation provides a good explanation on how suites work.
Use the TestSuite as @romulo-a-ceccon described for special preparations for each test suite.
However I think it should be mentioned here that Unit tests are ment to run in total isolation. Thus the execution flow is setup-test-teardown which should guarantee that each test run undisturbed by anything the other tests did.