ActiveTest: Examination, Part I: Removing Transparency
Posted by Mathew Abonyi Mon, 01 Jan 2007 03:34:58 GMT
The first abstraction I made was to change assert_get_success and its equivalents (get_failure, post_success, etc.) into an abstract idea of common test cases. Obviously every application is going to be treated differently, but to make a suite of tools to remove the most common tests seemed like a useful thing to extract—it’s DRY.
Consequently, I had the following in Test::Unit::TestCase:
class << self
def test_should_index_items
define_method(:test_should_index_items) do
assert_get_success :index
end
end
endI then abstracted it a little:
class << self
def test_should_get_with_success(action = :index, parameters = {})
define_method("test_should_#{action}_item") do
assert_get_success action, parameters
end
end
endThis is basic DRYing up. However, I have at this point already lost sight of the simplest benefit of writing out test cases with Test::Unit: documentation. If someone else uses this, the only thing they know is that their GET succeeds… but in what way? I began documenting what each method does and extracting more and more complex cases which may be ‘common’. Documenting these methods hid the general fault, which was making the entire testing process opaque to the user. Tests started to look like this:
class TestSomething < ActiveTest::Base
test_should_get_with_success :index
test_should_get_with_success :show, :id => 1
test_should_get_with_success :new
test_should_get_with_success :edit, :id => 1
endSo my first mistake was removing transparency without thinking about what I was beginning to lose. This is quite project-specific. In most cases, making methods opaque and useful is a good thing, but in the case of ActiveTest, it needs to be flexible and transparent. It is hard to beat a series of asserts.[1]
This mistake is probably my least offensive, because some, including myself, may like this feature just to remove all those irritating test_should_index_items, especially when you are writing new controllers left and right.
What Was I Thinking?
I thought that the documenting aspect of testing was purely outlining what everything should do, rather than describing what everything should do. My original idea was to make it easier to document and test at the same time by outlining the cases in each suite. Just in terms of line ratios, I now had a 5-line method which let me write a test case in 1 line. Not bad. It quickly paid for itself because it catered to :index, :new:, :show and :edit. However, I lost all the expressiveness of showing what is being tested.
Coming Up Next: Abstracting Without Basis…
Footnotes
1 It can be done. In fact, the next generation of Active Test, while rather different, frees up the tester to think completely about the behaviour of his code. I will trade in the brevity of test cases for the flexibility of defining them (for anything, whether Rails application, plugin, gem or 60-line file).
