Login Register

d-rails progress... testing 1, 2, 3.

Ahh, it feels good to come back from a much-needed week long vacation following final exams. I know you all have been wondering what I've been up to, aside from enjoying my time in the sun and drinking margaritas. So for d-rails, the word of the week this week is testing.

Since we want to ensure d-rails is an easy drop in replacement, the behavior of the d-rails helper functions must be exactly the same as the existing helper functions which rely on prototype as their underlying library. The current rails distribution uses unit tests to test the helper functions, but these are only syntactic string comparisons which don't really test behavior in the same way that we need to test in d-rails. Here's an example of a test in prototype_helper_test.rb

def test_form_remote_tag_with_method
    assert_dom_equal %(A BUNCH OF RANDOM HTML/JS THAT DRUPAL IS DELETING FOR ME BUT YOU DON'T NEED TO SEE IT TO GET THE POINT),
    form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast  }, :html => { :method => :put })
  end

As you can see, all this really does is compare the html/js spit out by the function call to a selected string. This type of testing is no doubt useful, as you want to ensure incremental changes you make don't cause your base test cases to fail. However, these tests are largely useless to us for testing that the behavior of the dojo helper overrides is equivalent to the default prototype implementation. What we really need is something that can compare the behavior of these in the browser.

I know a lot of you are yelling at the screen now, "Selenium! Selenium! Selenium!", which I agree is a good way to test real javascript behavior in real browsers. The problem I'm running into is not in selecting a test framework (I've pretty much settled on Selenium so far), but in actually getting the tests written.

I'll have to give some background on rails for you to appreciate the problems I'm encountering, so stick with me:

d-rails' current aim is to replace the built in prototype javascript helper methods in the ActionView::Helpers::PrototypeHelper module. A module in ruby is basically a mix-in for a class. To include a module in a class in ruby, you simply say include Qualified::ModuleName. In our current example, the prototype helper methods are instance methods applied to a controller in rails.

Controllers in rails process all incoming requests and spit out some output based on the request. Some data is shared between controllers and views, including the helper methods. So if we want to test this code in a real environment, we need to run these methods within the views or the controllers, and compare them. The problem comes when you want to have a d-rails prototype helper override method and a prototype helper method running in the same controller. (the reason we want something like this is so we can compare the two, side-by-side with selenium.)

I could go into a lot of details here, but the gist of it is that we can only have one module or the other loaded into the controller. More specifically, we can't switch modules in the midst of execution of a controller action (if we could, we could run link_to_remote with the default module, dynamically load the d-rails override module, the run link_to_remote again to get the dojo version of the function. Because of this, I've been trying to figure out a way selenium can observe the behavior of something on one page, load a new page and observe its behavior, then compare the two.

I know there is a lot of experience in the dev community with javascript testing tools, so maybe you guys can give me some advice.

There's also been something else that's bugging me about what we're doing now. I talked to a friend of mine, Brian Smith, who is part of the co-working space Downtown Cartel (which happens to be right down the street from me), and he was telling me about how javascript helpers in rails are evil.  The article makes a lot of good points, and I'm not entirely sure that helpers really fit the dojo paradigm. (maybe some of you can let me know after reading that article)

I also ran across this post written about a month ago about writing your rails views in javascript, and it seemed to vibe well with the way I've seen dojo being used in practice.  I'd really, really like to hear your thoughts on this.  I don't know the best ways to use dojo in practice, but I'd like for rails developers to be doing it the same way as everyone else.  The rails community is very receptive to Domain Specific Languages (DSLs), and writing a DSL to create views in ruby which leverages dojo and uses it in the way it's really meant to be used seems like a good idea.  Any and all feedback is more than welcome.

separating code from content

Because of this, I've been trying to figure out a way selenium can observe the behavior of something on one page, load a new page and observe its behavior, then compare the two.

iframes? And code to marshal the iframes in the 'parent' test? I guess you've looked at DOH for JS testing - and Selenium provides a JS interface as well, which might make it easier to write tests depending on what you're doing. DOH will run in selenium as well :)

how javascript helpers in rails are evil.

Do they have to be? From reading that article, it's complaining about the implementation but not the concept - and I agree the implementation sucks. So why not do a nicer implementation? Something like dojo.behavior might be a good start, or at least a grounding of ideas to work from.

From the linked article:

<% for(var user in at.users) { %>
  <%= user.first_name() %><br />
<% } %>

Looks like horrible PHP/ASP nastiness that people wrote back in the day! Its a lot cleaner to put stuff in a data structure using a JSON lib which does proper escaping, then use code to access that data. Not writing code to write Javascript loops... ick.

Rob :)

rails and dojo

Can't comment on testing, but I went thru a rails/prototype to rails/dojo conversion earlier this year. Most of the prototype stuff got rewritten in a dojo.rails library and helpers got replaced with the equivalent functionalities (I removed scripto entirely). In general I was not happy with the way that AJAX is accomplished with rails/prototype so in many cases I re-factored functionality like autocomplete and date widgets. I think anyone considering a serious rails/dojo project should approach it the "dojo way" for new development. There is serious benefit to writing methods that handle dojo.data formated replies on the server-side and other dojo-specific data structures that just can't be copied from the existing dojo/prototype helpers.