Test scope issue

My tests are broken. I generally suck at writing tests, so please bear
with me.

require 'test/unit'
require '../life.rb'

class TestLife < Test::Unit::TestCase
  def setup
    @life = Life.new
  end

  def test_life_exists
    assert( @life )
  end

  def test_vivify_vivifies
    @life.vivify(2,-1)
    assert( @life.world[2][-1] )
  end

  def test_murder_kills
    @life.murder(2,-1)
    assert( [email protected][2][-1] )
  end
end

I seem to be having a scoping issue here, where the changes made in
test_vivify_vivifies are not applying to @life in the general case; they
go away after test_vivify_vivifies ends, so that test_murder_kills
errors
out because @life.world[2] doesn’t exist at all at that point.

I have verified that when I run the code in life.rb using irb, the
@life.vivify actually gives me what I expect, and @life.murder thus
works
perfectly well there. Actually, I don’t even use the @ for an instance
variable when doing that; I only included it here to avoid scoping
issues
with local variables, but I seem to be having different scoping issues
as
a result. It so far seems to be only when running tests that there is
an
error.

I’m probably doing something stupid, but I have not yet seen it.

Each test method gets a new @life instance because the setup method runs
before each test. The theory is each test should run without side
affects
from other tests. I am no testing expert either, but I would write your
test in one method.

def test_vivify_and_murder
@life.vivify(2,-1)
assert( @life.world[2][-1] )
@life.murder(2,-1)
assert( !@life.world[2][-1] )
end

Again, I’m sure this is considered poor style and not pure TDD/BDD.

-Doug

On Sun, Jun 19, 2011 at 10:17:19AM +0900, Douglas S. wrote:

end

Again, I’m sure this is considered poor style and not pure TDD/BDD.

I should have read a bit more closely about setup, I guess. I had no
idea that was where the problem existed, though.

Thanks for the information! I’ll make good use of it.

On Saturday, June 18, 2011 08:17:19 PM Douglas S. wrote:

end

Again, I’m sure this is considered poor style and not pure TDD/BDD.

You generally want one assertion per test. More doesn’t hurt, but you
probably
still want a separate ‘test_vivify_vivifies’ method.

Also, if you find yourself writing a lot of tests which want a life
already
vivified, you may want to write another test class which does that in
its
setup. I’m not sure of the best way to do that in Test::Unit, though. I
think
I end up doing a lot of things like this in RSpec:

describe ‘A life’ do
before :each do
@life = Life.new
end

it 'should exist' do
  @life.should_not be_nil
end

describe 'A vivified life' do
  before :each do
    @life.vivify(2,-1)
  end

  it 'should exist in the world' do
    @life.world[2][-1].should_not be_nil
  end

  it 'should be killed when murdered' do
    @life.murder(2,-1)
    @life.world[2][-1].should be_nil
  end
end

end

Be careful with this, though. While DRY (Don’t Repeat Yourself) is a
good
principle in developing actual code, it’s often better to have explicit
readability in tests than implicit magic to avoid repeating yourself.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs