testing and requiring

I

Iain Barnett

Hi,

I have an app/gem dir structure looking like this:

appname (dir)
Rakefile
lib (dir)
appname.rb
appname (dir)
class1.rb
class2.rb
t (dir)
class1.t
class2.t

The appname.rb handles all the requires when the app is run.

In the rakefile I've got this task, which I can run as `rake test`:

# desc "Run basic tests"
Rake::TestTask.new("test") { |t|
t.libs =3D [lib_dir, test_dir]
t.pattern =3D 't/*.t'
t.verbose =3D true
t.warning =3D true
}


I've a couple of questions. How do I require the classes so that I can =
run test files individually if needed - do I put the requires in the =
test files themselves, or perhaps the rakefile, but then what's the best =
method for working out the right path to the class files from wherever =
the test is being run?
=20
Secondly, since the classes are all wrapped by `module appname` does =
that mean the tests need to be wrapped in it too?

I'd be grateful for any suggestions or pointers.

Regards,
Iain=
 
R

Ryan Davis

Hi,
=20
I have an app/gem dir structure looking like this:
=20
appname (dir)
Rakefile
lib (dir)
appname.rb
appname (dir)
class1.rb
class2.rb
t (dir)
class1.t
class2.t

Please don't do this. You're not in perl/whatever anymore, you're in =
ruby. Idiomatic ruby projects name their test directories "test" (or =
"spec") and name the test files as "test/test_class1.rb" (or =
"test/class1_test.rb" in rails land).
The appname.rb handles all the requires when the app is run.
=20
In the rakefile I've got this task, which I can run as `rake test`:
=20
# desc "Run basic tests"
Rake::TestTask.new("test") { |t|
t.libs =3D [lib_dir, test_dir]
t.pattern =3D 't/*.t'
t.verbose =3D true
t.warning =3D true
}

If you do things properly, you don't need to define your own TestTask. =
Projects like hoe or jeweler will do everything for you cleanly and =
automatically.
I've a couple of questions. How do I require the classes so that I can =
run test files individually if needed - do I put the requires in the =
test files themselves, or perhaps the rakefile, but then what's the best =
method for working out the right path to the class files from wherever =
the test is being run?

If you want to be lazy, you have each test file require "appname" since =
it pulls in everything else. If you want to be a software engineer, you =
have each file require whatever it directly depends on, so =
test/test_class1.rb only requires "appname/class1".
Secondly, since the classes are all wrapped by `module appname` does =
that mean the tests need to be wrapped in it too?

I generally do a 1:1 mapping between an implementation namespace and a =
test namespace such that X::Y::Z is tested by TestX::TestY::TestZ. =
autotest works this way to map test failures back to their =
implementations. Many people don't agree with me on this, but they're =
wrong :p. On the test side is a more arbitrary, but what I'd recommend =
is that you DO NOT infect your implementation namespace with your tests. =
Things can get messy that way.=
 
I

Iain Barnett

Idiomatically, you set up the $LOAD_PATH appropriately for each test.

You could run your tests individually from the command line like this:

# cd to top directory
ruby -Ilib t/class1.t

(where t/class1.t contains "require 'appname/class1'" at the top of
course)

If you don't like having to specify -Ilib when running individual tests,
then the solution is some variant of the following. Put a file called
"boot.rb" at the top level of your project, which contains

$:.unshift File.expand_path("#{File.dirname(__FILE__)}/lib")

Then at the top of each t/foo.t file put:

require "#{File.dirname(__FILE__)}/../boot"

You can use this in bin/foo as well. By using this file for each point
where your app starts, you should only ever have to require 'appname' or
require 'appname/class1', never require 'lib/appname'

If this file is *only* for supporting tests, not shared with any other
part of your app, then you might want to put it inside the t/ directory
instead, and adjust the requires appropriately.

HTH,

Brian.

Thanks for the advice, much appreciated.

Regards,
Iain
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,696
Latest member
BarbraOLog

Latest Threads

Top