thoughtbot/shoulda-context

setup block run multiple times

Closed this issue · 4 comments

We need to have an option to run the setup block once. Maybe that would be called setup_once or setup_context_once, doesn't matter. The functionality is just needed.

#!/bin/env ruby

require 'rubygems'
require 'test/unit'
require 'shoulda'

class ShouldaTest < Test::Unit::TestCase
    context 'First level' do
        setup do
            puts "First level setup"
        end

        context 'Second level' do
            setup do
                puts "Second level setup"
            end

            should 'test #1' do
                puts 'test #1'
            end

            should 'test #2' do
                puts 'test #2'
            end
        end

        should 'test #3' do
            puts 'test #3'
        end
    end
end

{noformat}
$ ./test/unit/shoulda_test.rb
Loaded suite ./test/unit/shoulda_test
Started
First level setup
Second level setup
test #1
.First level setup
Second level setup
test #2
.First level setup
test #3
.
Finished in 0.00036 seconds.
{noformat}

The expected results is "First level setup" block run only once for context "Second level".

Basically what you're saying is that tests should depend on each other, and this is a very bad practice. One test should not set up the conditions for the next test. You should be able to run each test independently and run the tests in any order you like. When tests depend on each other, then the first one to fail causes a cas- cade of downstream failures, making diagnosis difficult and hiding downstream defects.

@travisjeffery, I disagree.

  1. Dependency. Nested setup blocks are test-dependent per se, otherwise you would just have 1 big setup declaration in the top context without any setup blocks in nested contexts. The reason why people declare them at "lower" layer is because their deeply nested tests require additional common routines.
  2. Difficult diagnosis with failures in setup/teardown blocks. This problem exists right now, so by implementing setup_once we won't make it any worse. For ex., when a setup block fails, user is presented with very misleading message that a test failed, while in reality it's the setup block that failed. We can argue long time what's better, but I think there should be an option to configure the behaviour.

The real reasoning behind my request was that I needed to start a long-running, heavy, expensive (in all means) remote service that written tests would test against. The remote service's state is test-independent, it just starts once and then processes the incoming requests. With current code, the service is started & stopped on each test which annoys hell lot of me - it takes time, resources, energy, it kills innocent people in Africa.

Mock the service, write a interface/facade that your production and test code test. Run your tests against the actual service periodically/on major upgrades to the API to sanity check your mock.

In general your setup/teardown should never fail.

If you want to hack on this and add setup_once then I'll consider it.

Im guessing this never got created?