First I recognize that these questions might be straying a little
from the scope of this mailing list, but I haven’t been able to find
a more appropriate venue; if anyone can point me to a better venue,
I’d be very appreciative.
I’ve been using two of the ZenTest addons – autotest and Test::Rails
– and I’ve been running into a few problems as well as wondering
what’s considered best practices.
The issues:
Test::Rails doesn’t seem to play well with autotest, which is odd
as they are part of the same distribution. Specifically tests
extending from Test::Rails::TestCase don’t seem to respect
transactional fixtures, but only when run under autotest. Under rake
test, they work find. Invoked as a single test from the command-line
they work. No errors pop-up in the log, and it sure looks like the
Rollback is being issued, but cruft is left in the database. I’m not
sure how to continue investigating this… I see this problem in
projects where I’ve had to add some of the tweaks to help with
foreign key issues in order of fixture deletions as well as in
“stock” projects without such tweaks.
Refactoring controller test cases – I aggressively refactor test
cases, along the lines of Astel’s book, so I’ll commonly have 3-6
test cases (classes) per controller. Eric H. has already helped
me figure out how to use the @controller_class_name variable in an
abstract intermediate class between ControllerTestCase and my test
cases to let Test::Rails::ControllerTestCase resolve the file->class
mapping. However this code is getting repetitive between controller
trees
def setup
return if convert_classname == File.basename
(FILE,"_abstract.rb")
@controller_class_name = File.basename
(FILE,"_test_abstract.rb").classify
super
end
def convert_classname
self.class.to_s.tabelize.singularize
end
Notice that none of the code is different for the different
controller tress, but it does make use of the magic FILE.
I’ve tried introducing another layer between ControllerTestCase and
the abstract per controller test cases, like so:
class MyRailsControllerTest < Test::Rails::ControllerTestCase
def setup(filename="")
return if filename==""
return if convert_classname == File.basename
(filename,"_abstract.rb")
@controller_class_name = File
(basename,"_test_abstract.rb").classify
super() # drop the filename parameter
end
def convert_classname
self.class.to_s.tabelize.singularize
end
end
class TypicalControllerAbstractTest < MyRailsControllerTest
fixtures :typical_fixture
def setup
super(FILE)
end
end
Now I can extend from TypicalControllerAbstractTest for all my tests
without repeating the same class lookup code. The remaining setup
still isn’t as DRY as i would like as its repeated in each controller
tree. I’ve thought about developing a technique to climb the class
tree looking for a classname ending in “AbstractTest” and using the
preceding string to set the controller class name, which should let
MyRailsControllerTest handle all the mapping issues. I’ll still want
the TypicalControllerAbstractTest class though for the shared
fixtures, and possibly shared custom assertions tailored for that
controller.
Does anyone have any comments, suggestions, feedback on such a
refactoring?
If I continue down this path, I’ll want to look into modifying the
controller generator to produce my *ControllerAbstractTest" class as
well as a descendent for holding initial tests. Are there any
gotchas to watch out for when re-opening a stock generator?
Finally a best-practices type question –
As Test::Rails splits functional tests to controller and view
tests (stored in test/controllers and test/views) respectively and as
the resulting tests are more like unit tests than before, I thought
about moving them into a new directory structure:
test/unit/model
test/unit/controller
test/unit/view
test/integration
I’ve heard of a few people doing (basically the Rails default +
Test::Rails default, with slight tweak)
test/controller/
test/model/ – this is the slight tweak, and typically receives mot
of what would have be in unit
test/view
test/unit — normally left empty
test/functional – normally left empty
test/integration
Of course in either case minor tweaks are needed to rake tasks and/or
rcov, etc, but that’s a side issue.
Any thoughts?
Thank you
Eric