Rob Olson's blog
Many people use the ultra popular Paperclip library to handle file attachments in Rails. Unfortunately the Paperclip documentation does not cover how to stub out calls to ImageMagick in your test suite. Without the proper stubs in place a test suite that uses Paperclip will take much, much longer to run.
In the grease your suite presentation by Nick Gauthier it has a slide titled Quickerclip that describes what needs to be done to spend up Paperclip in tests, basically you need to keep it from shelling out to ImageMagick. Alas, the presentation does include code for how to achieve Quickerclip.
As the presentation shows Paperclip.run is the method that needs to be changed. The first parameter passed to Paperclip.run is the ImageMagick command be executed. Paperclip uses the identify and convert commands. The identify command is used to determine the dimensions of an image. The convert command is the really heavy one that does image manipulation and thumbnail generation. Here is a redefinition of Paperclip.run with sensible behavior for tests.
module Paperclip
def self.run cmd, params = "", expected_outcodes = 0
case cmd
when "identify"
return "100x100"
when "convert"
return
else
super
end
end
end
class Paperclip::Attachment
def post_process
end
end
Redefining post_process in Paperclip::Attachment is an optional additional optimization. In Paperclip, post_process eventually calls Paperclip.run("convert") and by short-circuiting the method earlier in the chain we save a few cycles.
Ask for Help
"Is there a good way to temporarily redefine a method on a controller during a functional test?"
Reopening a controller and overriding a method affects all tests in a suite. Is there a good way to redefine a controller method for a single test?
Assertions such as assert_select, assert_tag, and css_select are powerful tools in view tests. Since view helpers generate a chunk of HTML, it is sometimes practical to use these assertions to test their return value.
If you attempt to use assert_select it will fail because there has not been a call to render, as is done in a view test. To get around this you can store the result of the helper method in @response.body. Once @response.body is populated, the assertions will work like expected.
Update: For people using RSpec, Pat Maddox posted a helpful suggestion in the comments showing how to use have_tag to accomplish the same thing in RSpec style.
Example
describe TagsHelper do
describe "#tag_list"
describe "when the user is not an admin"
it "should not have links to delete the tags" do
@response.body = helper.tag_list
assert_select "a", 0
end
end
end
end
I like Autotest because it allows me to stay within my code editor and let my test suite run automatically in the background. After each run I get a nice, unobtrusive, growl notification informing me whether my most recent change caused the tests to fail or pass.
It used to be that setting up and configuring Autotest for the OS X with pretty growl notifications was a nontrivial task. I remember that I spent several hours getting it working a year ago. However, there has been several developments with Autotest in recent months that greatly simplify the process. One of those enhancements is that Autotest can now use FSEvent introduced in OS X Leopard so that it no longer has to continuously poll the filesystem. This has the advantage of vastly reducing Autotest's CPU usage when idle.
