Automated Testing with Ruby

December 8th, 2008

The fifth Australian Open Source Developers’ Conference was held last week in Sydney. In addition to helping organise the conference, I was fortunate enough to be one of the Ruby presenters.

View SlideShare presentation or Upload your own. (tags: osdc osdc2008au)

Naturally, these slides were designed to assist my presentation rather than contain all the content. Indeed, the inclusion of some of the slides may beg some questions so I thought it may be helpful to add some explanation here.

Reminiscing about Testing

Each of us programmers is on a specific journey, especially when it comes to testing. Early in my professional career I was taught how to unit test program modules written in PL/I. However, the drivers for those tests had to be written in Job Control Language (JCL) – an experience I am not in a hurry to repeat.

Many years later, having escaped from working on mainframes, I discovered JUnit. This was a fundamental tool in my early experience of test driven development and refactoring. When I began exploring Ruby and Rails, I was eventually introduced to autotest, which I considered another quantum leap forward in the realm of automated testing.

Testing Tools

In 25 minutes there was obviously a limit to the number of Ruby testing tools I could cover. So, having quickly explained the benefit of autotest and touched upon Test::Unit, I moved on to describe some tools that I have used in the last year.

RSpec

To make sure the audience was still awake, at this point I showed a cute photo of our family dog. My lame excuse was that he exhibits a wide range of behaviours and RSpec is all about specifying behaviour. My main example of using RSpec was for specifying a controller. This led on to a brief digression into consider what makes a good test and the use of mock objects to isolate unit tests and make them faster by avoiding unnecessary database I/O.

Integration Testing with Cucumber, Webrat and Selenium

I was pleased to be able to include Cucumber, Webrat and Selenium in my talk. It’s only fairly recently that I started using Cucumber in conjunction with Webrat or Selenium and I’m impressed. As Mike Koukoullis showed in his subsequent talk, developing with Cucumber is a very powerful approach, which fosters clear description of intent before development of any feature.

Speaking of other talks, Alister Scott used a lightning talk to share his enthusiasm for Watir, which looks like a good alternative to Selenium.

Test Data with Machinist

After briefly relating the motivation for developing alternatives to relying on fixtures for test data, I described Machinist, an elegant tool recently developed by Pete Yandell. When used in conjunction with Sham, Machinist provides a neat way of generating “blueprints” that can be used in Cucumber steps.

Other Tools

I briefly mentioned JavaScript unit testing tools that are the subject of a blog post by Dr Nic as well as touching upon Shoulda, which is well written up by Dave Thomas.

Philosophy

To round out my talk, I thought it was important to offer a few philosophical thoughts. In a nutshell my view is that, whilst it is important to remember that automated testing is just one of many error removal approaches, we can all benefit from investing in automated testing.

In my case, as well as practicing using these tools, I’m also looking forward to reading the upcoming title The RSpec Book by David Chelimsky and others.

Tags: osdc osdc2008au ruby automated testing rspec cucumber webrat selenium | Comments (0)

Rails Camp in the Adelaide Hills

November 23rd, 2008

I think I’ve just about recovered from last weekend’s Rails Camp in the Adelaide Hills. Whether I was hacking or socialising, as the hour got later each evening it just seemed easier to ignore the fact that I was going to pay later for the lack of sleep.

It was worth it though. This was the best attended Rails Camp yet with about 70 Rails developers converging from different parts of Australia. One of the aspects I like about these events is their self-organising nature. The unconference style encourages learning within small groups for much of the event. In my case I was determined to practice using Cucumber, Webrat and Machinist and benefited from the fact that several others were also cutting their teeth on Cucumber.

There are also plenty of opportunities to share with the whole group. At this camp I was fortunate that Pete Yandell, the author of Machinist, was one of those who spoke. I also thoroughly enjoyed the lengthy discussion which was precipitated by Pat Allan’s talk about Freelancing.

Quite apart from the learning opportunities, I appreciated catching up with other Rails developers I hadn’t seen for a while and making new friendships. I’m looking forward to my next Rails Camp already. Hopefully the number of attendees doesn’t increase. I think it has reached its limit for a good unconference.

Tags: railscamp rails unconference | Comments (1)

OSDC 2008 Earlybird registration closing this Friday

October 28th, 2008

OSDC 2008: Sydney

In exactly five weeks this year’s Open Source Developers’ Conference starts. As one of the organising committee it would be remiss of me not to alert you to the fact that if you register by this Friday you can take advantage of earlybird pricing.

The Facts

31st October: Earlybird registration closing

2nd December: Google Hackathon
3rd – 5th December: Conference Program
3rd December: Conference Dinner

Where

SMC Conference and Function Centre
66 Goulburn St
Sydney NSW 2000

The Main Conference

The Open Source Developers’ Conference 2008 is a conference run by open source developers, for developers and business people. This year we have talks covering Apache, Java, Ruby, Perl, PHP, Python, Testing and much more. Our keynote speakers this year are:

  • Larry Wall, the creator of Perl
  • Chris DiBona, Open Source Programs Manager for Google
  • Anthony Baxter, Python Evangelist
  • Pia Waugh, Consultant, Waugh Partners
  • Andrew Tridgell, Founder, Samba Team

Speakers on Ruby topics include:

  • Michael Koukoullis: “Story-based Web Development”
  • Dr Nic Williams: “How to package your Ruby code for distribution and sharing”

Check out the program for more information.

Google Hackathon

The day before the main conference, there will be an optional event. The Google Hackathon will consist of 3 coding workshops during the day with attendance limited to a maximum of 100 people/workshop. To register for any of the workshops, you must have registered for the 3 day OSDC 2008 main conference.

Our Sponsors

Naturally the organising committee is most grateful to our sponsors: Google, Corporate Express, Sun Microsystems, Strategic Data, Obsidian Consulting Group, IBM, Zacware/Freeway, ACS, Net Logistics, GROX, UTBox, Internode and Linux Magazine.

Tags: osdc2008au | Comments (1)

Dynamic CSS with Rails

October 24th, 2008

I’ve sometimes wondered why CSS isn’t more dynamic.

Take, for example, the styles applied to the sub-menu on the services page of this site. To achieve the highlighting of the current service, I combine a Rails view and CSS as follows:

The Rails View

<div id="<%= @current_service.name %>">
  <div id="secondaryNav">
    <ul>
      <% @services.each do |service| %> 
        <li class="<%= service.name %>"><%= link_to service.heading, service_path(service) %></li>
      <% end %>
    </ul>	
  </div>
</div>

The CSS

#agileweb #secondaryNav .agileweb a,
#java #secondaryNav .java a,
#coaching #secondaryNav .coaching a,
#mentoring #secondaryNav .mentoring a,
#overview #secondaryNav .overview a,
#advice #secondaryNav .advice a {
  color: #99CC00;
  text-decoration: underline;
}

Handling a new service

That does the trick nicely until I decide to add a new service. Wouldn’t it be nice to have that CSS regenerated dynamically whenever I create, update or delete a service?

Enter a new Ruby module:

# lib/dynamic_css.rb
module DynamicCss
  def generate_services_nav_links_css
    return if RAILS_ENV == "test"
    FileUtils.cd File.expand_path("public/stylesheets", RAILS_ROOT)
    File.open("servicesnav.css", "w") do |out|
      service_names = []
      services = Service.find :all
      services.each { |s| service_names << s.name }
      service_names.each_with_index do |name, i|
        out.print "##{name} #secondaryNav .#{name} a"
        if i + 1 < service_names.size
          out.puts ","
        else
          out.puts " {"
        end
      end  
      out.puts "  color: #99CC00;"
      out.puts "  text-decoration: underline;"
      out.puts "}"
    end
  end
end

Then a small adjustment to invoke the css regeneration via a filter in my admin services controller:

class Admin::ServicesController < AdminLayoutController
  include DynamicCss
  
  after_filter :generate_services_nav_links_css, :only => [:create, :update, :destroy]

# remainder of controller

end

Lastly, to ensure that the servicesnav.css file exists by the time one of the public services pages is requested:

# config/initializers/services_nav_css.rb

include DynamicCss

generate_services_nav_links_css

Admittedly this is a specific case, but this example shows that it is relatively straightforward to dynamically generate CSS within a Rails app if required.

Tags: rails css | Comments (3)

Code Syntax Highlighting

October 17th, 2008

Having just implemented code syntax highlighting in this blog in addition to Textile formatting, I thought I’d share how I did it.

After a little research, I decided that Arya Asemanfar’s tm_syntax_highlighting plugin looked the most promising. Arya’s blog post about it was particularly helpful.

Prerequisites

Install the oniguruma system library (see link in the plugin README).

Install the ultraviolet gem, which will also install the textpow and oniguruma gems.

sudo gem install ultraviolet

1. Install the Plugin

./script/plugin install git://github.com/arya/tm_syntax_highlighting

2. Copy all themes from ultraviolet:

./script/generate syntax_css

3. Create defaults initializer

# config/initializers/tm_syntax.rb
TmSyntaxHighlighting.defaults = {:theme => "mac_classic", :line_numbers => false, :lang => "ruby"}

4. Create an application helper method to parse the Textile and code:

Note: I have used “c0de” instead of “code” here just to enable this code to be parsed!

# app/helpers/application_helper.rb
def parse_textile_and_code_syntax(text)
  text_pieces = text.split(/(<c0de>|<c0de lang="[A-Za-z0-9_-]+">|<c0de lang='[A-Za-z0-9_-]+'>|<\/c0de>)/)
  in_pre = false
  language = nil
  text_pieces.collect do |piece|
    if piece =~ /^<c0de( lang=(["'])?(.*)\2)?>$/
      language = $3
      in_pre = true
      nil
    elsif piece == "</c0de>"
      in_pre = false
      language = nil
      nil
    elsif in_pre
      code(piece.strip, :lang => language, :theme => "mac_classic")
    else
      RedCloth.new(piece.strip).to_html
    end
  end
end

5. Use the helper in the views

<%= parse_textile_and_code_syntax(@blog_post.post) %>

6. Add CSS for horizontal scrolling

pre {
  margin: 10px 10px;
  padding: 10px 10px;
  line-height: 15px;
  overflow: auto;
  font-family: "Monaco", "Courier New", courier;
  font-size: 12px;
}

Tags: ruby rails syntax highlighting | Comments (0)