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

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

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.

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
}

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 Sep 26, 2010, at 09:57 , Iain Barnett 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 26 Sep 2010, at 21:59, Ryan Davis wrote:

Iain Barnett 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.

···

--
Posted via http://www.ruby-forum.com/\.

Thanks for the advice, much appreciated.

Regards,
Iain

···

On 27 Sep 2010, at 15:08, Brian Candler wrote:

Iain Barnett 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.