Standup 04/30/2007
Interesting Things
- MoniTwitter is live! Check out the coolest site-monitoring mash-up in the history of site-monitoring mash-ups!
- When you use
:dependent => :destroyto cascade deletes, make sure you test them well! This really saved our bacon during a major rafactoring.
Ask for Help
- "I always forget how to submit an HTML form with a link in Rails..." Here you go!
<%= link_to_function('Link Name', "$('form_id').submit()") %>
Total Stand-up Meeting Time: 20:00 minutes
Standup 04/27/07: Testing File Uploads
The setup:
I'm told file uploading is a pain to test. We needed to. So we cruised through the tubes over to ruby-doc.org to check out the Net::HTTP rdoc -- only to find that Net:HTTP::Post does not support multipart uploading and files. What to do, what to DO?!?
The research:
Some googling later, we find this article showing how to do it. A little copy-paste, a small spike later, and we have an external script capable of uploading files into our web-apps. But, lets brain-storm a little...
- How can we make it better?
- What would be a nice interface?
Well, the first step is to change the script such that it can be more easily integrated into rake test:functionals: make it less script-y; more library. The interface is somewhat inspired by the basic_auth method. All you have to say is Net::HTTP::Post.new().multipart_params = {}? You give it a hash, and it takes care of the rest. Huzzah! So lets open up Net::HTTP::POST and give it some new methods. Time for some CODE!!!
The Code
require 'net/https'
require "rubygems"
require "mime/types"
require "base64"
require 'cgi'
class Net::HTTP::Post
def multipart_params=(param_hash={})
boundary_token = [Array.new(8) {rand(256)}].join
self.content_type = "multipart/form-data; boundary=#{boundary_token}"
boundary_marker = "--#{boundary_token}\r\n"
self.body = param_hash.map { |param_name, param_value|
boundary_marker + case param_value
when String
text_to_multipart(param_name, param_value)
when File
file_to_multipart(param_name, param_value)
end
}.join('') + "--#{boundary_token}--\r\n"
end
protected
def file_to_multipart(key,file)
filename = File.basename(file.path)
mime_types = MIME::Types.of(filename)
mime_type = mime_types.empty? ? "application/octet-stream" : mime_types.first.content_type
part = Q|Content-Disposition: form-data; name="#{key}"; filename="#{filename}"\r\n|
part += "Content-Transfer-Encoding: binary\r\n"
part += "Content-Type: #{mime_type}\r\n\r\n#{file.read}"
end
def text_to_multipart(key,value)
"Content-Disposition: form-data; name=\"#{key}\"\r\n\r\n#{value}\r\n"
end
end
Oh the utility:
Now that's more like it. Hackish, since you have to stick headers into the request body, but effective. Notice the bit in there about MIME::Types. Did you see that? Yeah, we went there. Say it with me... Automatic mime type detection with a safe default. The absurd thing in there is that the MIME::Types gem (as of today) does not know about .rb files.
irb(main):007:0> MIME::Types.of('something.rb')
=> []
So now that you have that, it's just a simple use of Net::HTTP with a blizzock to upload a file in a functional test.
File.open(File.expand_path('script/test.png'), 'r') do |file|
http = Net::HTTP.new('localhost', 3000)
begin
http.start do |http|
request = Net::HTTP::Post.new('/your/url/here')
request.basic_auth 'lonely_user', 'really_long_password'
request.multipart_params = {'file' => file, 'title' => 'title'}
response = http.request(request)
response.value
puts response.body
end
rescue Net::HTTPServerException => e
p e
end
end
The questions:
So what do you think? How can this be made even better?
Standup 2.5
- Introductions. Anybody new? Any guests in the room?
- Help! Anybody need assistance?
- Neat! Interesting things we want to share.
- Status. Only if there's time -- project or individual reports.
(Based on Standup 2.0.)
Full-stack web app testing with Selenium and Rails
Brian Takita and Alex Chaffee gave a presentation at the SDForum Silicon Valley Ruby Conference over the weekend, entitled Full-stack web app testing with Selenium and Rails. We're going to do it again at Agile 2007 (and we'll have an extra half-hour next time, so we'll have time to do some interactive pairing with some hapless audience member).
Here are the slides, courtesy of SlideShare:
Silicon Valley Ruby Conference Report
Brian Takita and Alex Chaffee gave a presentation at the SDForum Silicon Valley Ruby Conference over the weekend, entitled Full-stack web app testing with Selenium and Rails (slides hosted at SlideShare).
We also attended a few talks (unfortunately we couldn't attend the whole thing). A few highlights:
Mongrel HTTP handlers.
From Brian:
I'm at Ezra's Mongrel HTTP Handler's talk and it looks like a way to improve Tracker's JSON performance.
The simple "Hello World" benchmark was something like this:
- Rails: ~121 req/sec
- Mongrel: ~900 req/sec
There is an in-process mode that a mongrel HTTP handler can be run in. This handler will be run in process of your rails app. You have access to Active Record. It just avoids ActionController.
Ezra wrote a framework named Merb (Mongrel + ERB).
Also, mongrel is thread safe. Also, Ezra shared that he wants to avoid magic in Merb.
Ezra's slides are online now.
Here's what Josh wrote about Merb.
Heckle
Heckle is a framework for doing "mutation testing" (like Jester for Java). Kevin Clark demoed it and it looks like a valuable addition to any Ruby build (though probably not as a requirement for a green build -- more like part of a nightly metrics run).
Microformats
Chris Wanstrath of Err the Blog gave a talk that was ostensibly about Web Services but that
actually ran a manic gamut from SOAP to
Microformats to
Firefox plugins to
command-line blogs to
mock object libraries.
His speaking style is deceptively laid-back -- if you don't pay close attention, especially to code examples, you'll miss entire open-source
civilizations being born and collapsing. Fortunately, I had just given a talk so my neurons were all juiced up,
which meant I could just barely keep up. Bottom line for microformats: gem install mofo.
Update: More Slides
Check out SlideShare's svrc tag for more slide presentations from the conference, including Ezra's Mongrel Talk.
Standup 04/23/2007
Interesting Things
Latest news from the "cool new stuff" front:
- Check out these very educational slides about Mongrel HTTP Handlers, which allow you to use Mongrel with ActiveRecord, but bypass ActionController and other aspects of Rails.
- Also check out Merb: Mongrel + Erb, a "little bitty lightweight ruby app server."
- Finally, Heckle, a mutation tester similar to Java's Jester.
Total Stand-up Meeting Time: 9:00 minutes
Keeping Your Design Three-Quarters-Baked
I just gave a talk at the Web 2.0 Expo with Leslie Chicoine of Satisfaction. We shared our insights into the challenge of integrating foundational design methods (interaction design, usability design, interface design, interaction design) into a team doing Agile development (rapid releases, week-long iterations, high feedback and communication). It was a lot of fun! The room was packed, the energy was high, and they laughed at our jokes!
Here are the slides:
You can also see the slides here at SlideShare. Let me know what you think!
The Challenge of Agile Design
I just gave a talk at the Web 2.0 Expo with Leslie Chicoine of Satisfaction. We shared our insights into the challenge of integrating foundational design methods (interaction design, usability design, interface design, interaction design) into a team doing Agile development (rapid releases, week-long iterations, high feedback and communication). It was a lot of fun! The room was packed, the energy was high, and they laughed at our jokes!
Here are the slides:
You can also see the slides here at SlideShare. Let me know what you think!
Standup 4/17/2007
Interesting Things
- Nesting a javascript generator within a javascript generator does not work:
<code>
new.rhtml:
link_to_function "myFunction" do |page|
page.insert_html :bottom, :partial => 'new_stuff'
end
_new_stuff.rhtml:
link_to_function "remove" do |page|
page.replace_html 'some_id', ""
end
</code>
The quotes in the nested JS are not escaped properly.
- The plugin team introduced new email validation for the User plugin. They covered this with functional/unit tests within the plugin but projects using the plugin will need to update their own Selenium tests.
Total Stand-up Meeting Time: 10:00 minutes
Standup 4/16/2007
Standup 04/16/2007
Help
- Problems with initial start up of CrusieControl daemon script. J of cc.rb can take a look.
- Running Selenium on IE7 remotely
Interesting Things
after_filteris called after the template is rendered, thus you cannot set instance variables in it and expect them to be available in the template. Theafter_filtermethod is good for post-render content manipulation or analysis such as gzipping, translating to pig latin or determining content-length. Perhaps it would be useful to add abefore_renderhook?- Remember integration tests are for full stack http testing (routes, REST, etc). Functional tests do not test full stack. Integration tests require some special handling.
- After a reload on an association proxy object, the reference becomes a true Array (they always respond true to
is_a?(Array). This means that none of the association proxy methods are available!
<code>
class Foo < ActiveRecord::Base
has_many :bar
end
foo = Foo.new
foo.bars.reload.build
NoMethodError: undefined method `build' for []:Array
</code>
Total Stand-up Meeting Time: 14:00 minutes








