Testing and requiring

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 = [lib_dir, test_dir]
t.pattern = ‘t/*.t’
t.verbose = true
t.warning = 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?

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

On Sep 26, 2010, at 09:57 , Iain B. wrote:

 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).

}
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.

On 26 Sep 2010, at 21:59, Ryan D. wrote:

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).

If it means that much to you, then ok.

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 won’t be using hoe or jeweler. Such is my wont.

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”.

My point is, should I be using relative paths to these files from the
test file (or rake file, or wherever), or is there a better way to
require the files? The idiomatic way seems to use lib/appname.rb to do
this for running the app, what about for tests? What if I have a
lib/appname/ext dir with changes to core classes, how do I add them in?

Regards,
Iain

On 27 Sep 2010, at 15:08, Brian C. wrote:

cd to top directory

instead, and adjust the requires appropriately.

HTH,

Brian.

Thanks for the advice, much appreciated.

Regards,
Iain

Iain B. wrote:

My point is, should I be using relative paths to these files from the
test file (or rake file, or wherever), or is there a better way to
require the files? The idiomatic way seems to use lib/appname.rb to do
this for running the app, what about for tests?

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.