I’ve been working on figuring out how to organize unit tests for BioRuby. If I had a higher tolerance for googling, I would probably find seven great ways to do this. In any case, here’s what I came up with.
Here’s the plan. Say you download the bioruby tar.gz file, and you unpack it into a directory called biorubyInstall. The directory structure should look something like
biorubyInstall/
lib/
test/
other stuff...where the lib directory contains the BioRuby source, and the test directory contains all the unit test code. I want my unit test suite to be as usable as possible. Therefore, I subject my solution to the following constraints:
- Regardless of where you run a unit test or unit test suite from, the code the tests run against should be the code in biorubyInstall/lib, not /usr/local/lib/ruby/site_ruby/…. That is, my tests test the local bioruby code, not bioruby code installed elsewhere on my filesystem.
- I should be able to run appropriate subsets of my test suite. Thus, if I organize my tests hierarchically in directories according to the hierarchical organization of the BioRuby source, then I should be able to run test suites for each of those subdirectories, and run each test case file individually.
- I should be able to run these test suites and test cases from any directory
This means that I have to mess with the Ruby load path so that tests and source code are loaded from the appropriate directories regardless of the value of PWD.
I name my test case files using the convention test_*.rb, e.g. for pathway.rb, test_pathway.rb. Within each subdirectory, I place a test suite file named after the subdirectory, e.g. in bio/ I add a file suite_bio.rb that runs all of the test case files beneath the bio directory. The top-level test suite I called all_tests.rb, but maybe suite_all.rb or just suite.rb would have been a better name.
I prepend the contents of each test case file with the following code:
require 'pathname' libpath = Pathname.new( File.join(File.dirname(__FILE__), [".."]*2, "lib") ).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath)
where 2 should be replaced with the number of directory levels below biorubyInstall at which the test_*.rb file sits. These lines of code ensure condition 1 above.
I prepend the contents of every test suite file with:
require 'pathname' testpath = Pathname.new( File.join(File.dirname(__FILE__), ".."*1) ).cleanpath.to_s $:.unshift(testpath) unless $:.include?(testpath)
where 1 this time is replaced with the number of directory levels below biorubyInstalls/test. I leave the 1 off if it’s just one. To include the test case files into test suite, require them using their full directory path beneath biorubyInstalls/test, so for
biorubyInstalls/
lib/
bio/
pathway.rb
test/
bio/
suite_bio.rb
test_pathway.rbyou would place the line
in suite_bio.rb.