I use a test-driven development approach to developing my web-application, stikis. As I add new features to the site, I write tests to ensure that the new code does what I intend it to do and does not break existing code. This approach to development is very well supported by the rails framework, and test-driven development is a great way to work, but testing is still difficult. When tests fail, it can be hard to understand why. Sometimes your brain hurts.
Here’s a little thing I did to make one aspect of failing tests easier to understand.
Typically, if I can’t immediately determine the cause of the error from the output of the functional test, I will set a breakpoint in the test with the debugger command and then run the test again so I can interact with the code where the test is failing. It’s particularly useful in this situation to be able to look at the TestResponse (@response) object, which includes a ‘body’ property that holds the text of the response. Typically this is the html code that would be rendered by a browser.
Although it’s really great to be able to read the contents of the response body, I’ve often found myself wanting to be able to see the response as it would display in the browser, rather than having to read and interpret html, which is what you get on the command line. Compare the top and bottom parts of the picture above so see what I mean (admittedly, the top picture would look a lot nicer if I used puts to print it).
To address this, I added a method to the @response object that does the following:
- Converts the response body to base 64 using the Base64 module from the ruby standard library.
- Format a data: URI for it using the response header mime-type and charset.
- Open Safari with the data URI as the location using the ‘rb-appscript’ gem.
Putting it all together
I first installed the rb-appscript gem…
$ sudo install gem rb-appscript
And then added the following code to my test_helper.rb file.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require 'appscript'
class ActionController::TestResponse
def show_in_safari()
type = self.headers['type']
body = Base64.encode64(self.body)
dataURI = "data:#{type};base64,#{body}"
sa = Appscript::app("Safari")
sa.document.end.make(:new => :document,
:with_properties => {:URL => dataURI}
)
end
end
With the gem installed and the extra method included in the TestResponse object, you can type the following at a breakpoint to open the response body in Safari (assuming your breakpoint is set in the body of the test case itself).
(rdb:1) @response.show_in_safari
Limitations
There are some limitations to this:
- It’s Mac only and browser specific (but a similar approach would work for other platforms/browsers).
- If Safari isn’t already running, it will open an extra window with your homepage.
- It doesn’t give focus to the new browser window. You have to switch windows manually.
- It’s fiddling around with the TestResponse class directly, which is probably poor form.
- Linked resources such as images, javascripts and stylesheets won’t be included.
- Relative links won’t work (but absolute ones should still be fine).