Unique Marketing, Guaranteed Results.

Culerity and Celerity, JavaScript enabled testing in Cucumber

June 8th, 2009 by fugufish

As you may know, testing JavaScript inesnsive applications using Cucumber can be a pain. There are several ways to handle this; Selenium, Watir and the like. The easiest way I have found however is by using Celerity a jRuby API for htmlUnit, a fully functional headless browser that completely supports JavaScript, and you don’t have to serve your application on jRuby to use it!. I was able to get Celerity to play nice duruing Cucumber tests by doing the following: First, you will need of course jRuby. The Culerity gem will start up Celerity in the jRuby environment, and proxy the actual browser through it. Download jRuby and extract it to wherever you want it located. In my case I put it in /opt, and set your PATH accordingly.

export PATH=$HOME/jruby/bin:$PATH

Next install the Celerity gem in jRuby (we are using the github version rather than the ruby forge version, as it provides a later version):

jruby -S gem install jarib-celerity --source=http://gems.github.com

Now install the Culerity gem. This provides the interface between Celerity and your environment without forcing you to run in jRuby

 gem install langalex-culerity --source http://gems.github.com

Place this in your test environment:

# config/environments/test.rb
 
config.gem "langalex-culerity", :lib => false

I call :lib => false here to avoid loading the gem. This is done in the file generated by culerity. Finally remove features/steps/webrat_steps.rb as it will conflict with Culerity, and run:

script/generate culerity

Enjoy! Culerity should have very similar syntax to webrat, however keep in mind you may see some differences that you may need to adjust.

Smarter Sequencing in Factory Girl

May 29th, 2009 by Brett Rasmussen

Hal Shearer and I monkey-patched Factory Girl’s sequencing capabilities to allow for pre-defined enumerations to loop through, instead of just infinitely incrementing numbers.

So instead of doing this:

  Factory.sequence :email do |n|
    "person#{n}@example.com"
  end

you could do something like this:

  Factory.sequence(:email, ['angela', 'brett', 'alec']) do |name|
    "#{name}@example.com"
  end

It will start over at the beginning when it’s gone through all of them:

>> Factory.next :email
=> "angela@example.com"
>> Factory.next :email
=> "brett@example.com"
>> Factory.next :email
=> "alec@example.com"
>> Factory.next :email
=> "angela@example.com"
>> Factory.next :email
=> "brett@example.com"

You can also hand it a range (the internal implementation on this is none too efficient, so don’t give it billions at a time):

Factory.sequence(:email, 50..60) do |n|
  "user_#{n}@example.com"
end
 
>> Factory.next :email
=> "user_50@example.com"
>> Factory.next :email
=> "user_51@example.com"
>> Factory.next :email
=> "user_52@example.com"

The infinitely incrementing counter is still available if you want it:

Factory.sequence(:email, %w[angela brett alec]) do |name,i|
  "#{name}_#{i}@example.com"
end
 
>> Factory.next :email
=> "angela_0@example.com"
>> Factory.next :email
=> "brett_1@example.com"
>> Factory.next :email
=> "alec_2@example.com"
>> Factory.next :email
=> "angela_3@example.com"
>> Factory.next :email
=> "brett_4@example.com"

This sort of thing is useful when you want two different factories to use the same sequence and have some overlap between the two groups. For example, we need a bunch of email addresses to test on, many of which share the same domain:

Factory.sequence(:name, %w[angela brett alec hal debbie tracey jared]) do |name,i|
  "#{name}_#{i}"
end
 
Factory.sequence(:domain, %w[something.com example.com mydomain.com]) do |domain|
  domain
end
 
Factory.define(:email_address) do |f|
  f.address { "#{Factory.next(:name)}@#{Factory.next(:domain)}" }
end
 
>> 20.times { ea = Factory.build :email_address; puts ea.address }
angela_0@something.com
brett_1@example.com
alec_2@mydomain.com
hal_3@something.com
debbie_4@example.com
tracey_5@mydomain.com
jared_6@something.com
angela_7@example.com
brett_8@mydomain.com
alec_9@something.com
hal_10@example.com
debbie_11@mydomain.com
tracey_12@something.com
jared_13@example.com
angela_14@mydomain.com
brett_15@something.com
alec_16@example.com
hal_17@mydomain.com
debbie_18@something.com
tracey_19@example.com

For our last trick, the reset method returns both the looping index and the infinite counter back to zero:

>> Factory.reset :name
>> Factory.next :name
=> "angela_0"

Here’s the code to make it happen:

class Factory
  def self.sequence(sequence_name, enum = nil, &blk)
    @@sequences ||= {}
 
    enum = enum.to_a
 
    @@sequences[sequence_name] = {
      :enum => enum,
      :index => 0,
      :infinite_counter => 0,
      :template  => blk
    }
  end
 
  def self.next(sequence_name)
    seq = @@sequences[sequence_name]
 
    retval = case seq[:template].arity
      when 1
        seq[:template].call(seq[:enum][seq[:index]])
      when 2
        seq[:template].call(seq[:enum][seq[:index]], seq[:infinite_counter])
    end
 
    seq[:index] = (seq[:index]+1 == seq[:enum].size) ? 0 : seq[:index]+1
    seq[:infinite_counter] += 1
    @@sequences[sequence_name] = seq
    retval
  end
 
  def self.reset(sequence_name)
    @@sequences[sequence_name][:index] = 0
    @@sequences[sequence_name][:infinite_counter] = 0
  end
end

Just put that into some file–perhaps in your rails lib directory–and make sure that file gets required–probably in your rails config/environment.rb. When doing it by hand like this, you’ll want to make sure your library file is loaded after the factory_girl gem is loaded, or you’ll get weirdness like methods you’ve overridden acting in non-overridden ways and the like; config.after_initialize in your environment.rb’s Rails::Initializer block is your friend.

You can also now use the gem BrettRasmussen-factory_girl from gems.github.com. I mean to submit it as a patch back to the original factory_girl, which I’m sure I’ll have time to do Any Day Now.

Chuck’s Ruby Indexer

May 22nd, 2009 by Chuck Wood

I was messing around with ruby a little and decided to write a little indexer that would tell me what the most common words were in my files. It’s really kind of a dumb program, but it was interesting what it turned out when I ran it against my code. The most common word was frequently the word ‘the.’ ‘the’ is not a commonly used variable or function in Ruby. So I looked at my code and realized that it was heavily commented, yielding frequent ‘the’s.

That being said, I’m curious to see what other people find running the indexer against their code. You can get it at http://github.com/woody2shoes/indexer/tree/master. Please comment and let me know what your code looks like.
Read the rest of this entry »

How to do Benchmarking with Ruby

May 21st, 2009 by Alan Carl Mitchell

Benchmarking with Ruby is super easy. There is already a built in class–Benchmark–that will do all of the heavy lifting for you.

If you want to do basic benchmarking, Benchmark.bm is the easiest way to go. Take a look below. Here we are going to test three ways to do looping in Ruby and see which one we like best.

require 'benchmark'
 
n = 5000000
 
Benchmark.bm do |x|
  x.report("for loop:")   { for i in 1..n; a = "1"; end }
  x.report("times:")      { n.times do   ; a = "1"; end }
  x.report("upto:")       { 1.upto(n) do ; a = "1"; end }
end

This will produce output something like this:

               user     system      total        real
for loop:  0.727000   0.000000   0.727000 (  0.727030)
times:     0.571000   0.000000   0.571000 (  0.571588)
upto:      0.523000   0.000000   0.523000 (  0.522947)

If we use Benchmark.bmbm, then it will do a ‘rehearsal’ run first in order to better equalize the garbage collection environment of the code inside the block so that hopefully we get more realistic timings.

require 'benchmark'
 
n = 5000000
 
Benchmark.bmbm do |x|
  x.report("for loop:")   { for i in 1..n; a = "1"; end }
  x.report("times:")      { n.times do   ; a = "1"; end }
  x.report("upto:")       { 1.upto(n) do ; a = "1"; end }
end

This will produce output something like this:

Rehearsal ---------------------------------------------
for loop:   0.756000   0.000000   0.756000 (  0.756298)
times:      0.477000   0.000000   0.477000 (  0.476855)
upto:       0.527000   0.000000   0.527000 (  0.526522)
------------------------------------ total: 1.760000sec

                user     system      total        real
for loop:   0.751000   0.000000   0.751000 (  0.751067)
times:      0.516000   0.000000   0.516000 (  0.515874)
upto:       0.581000   0.000000   0.581000 (  0.581254)

Alternately, you can use the Benchmark.realtime method like this:

puts "for loop: #{Benchmark.realtime {for i in 1..n ; a = "1" ; end}}"

and get something like this:

for loop: 0.682438850402832

Ruby newbie iteration musings

May 5th, 2009 by hals

First off I must note how nice it is that semicolons, and several other punctuation items, are optional.

Another nice thing I have been introduced to is the iterator. In most cases it completely replaces the old for loop. 

var.each {|x| ….}     

or

for x in var {……}

seem much cleaner and easier to write than

for (int i=0; i<10; i++) {…; …;}

Extending this makes it handy to work with multiple parameters. Let’s say that you want to pass in a variable number of arguments, that can also be hashes.

One way of working with them in the method would be as follows:

class Ema

def initialize(p1, p2, *p3)  # the ‘*’ will push arguments 3…n into p3 as an array

# then you might access parameter3 with one of the following .each variants:

def showMe

    @p3.each do |s|    #this gives you each element of the array - 

      puts “  p3: s = #{s}”

        s.each_key do |y|     #each element is a hash, so this gives you the keys

          puts ”     #{y} = #{s[y]}”

        end

        s.each do |y,z|       #this will give you the key, value pairs

          puts ”     #{y} = #{z}”

        end

        s.each do |r|        #and this gives you the key,value in an array

          puts ”     #{r[0]} = #{r[1]}”

        end

    end

end

 a = Ema.new(“one”, “two”, {“apple” => 3}, {“pear” => 1}, {“grape” => 5}, {“kiwi” => 33})

a.showMe

Ruby on Rails Spotlight Search in Mac OS Leopard

April 15th, 2009 by Chuck Wood

Have you ever wished you could search the Ruby on Rails API with Spotlight? It turns out that you can!

Mac OS X Leopard’s Spotlight search will search through dictionaries you install on your machine and enable. And, it just turns out that such a dictionary exists for Ruby on Rails written by Priit Haamer. Here’s how to set it up:

Read the rest of this entry »

Ruby Chop vs Chomp

April 14th, 2009 by jaredd

When you receive user input from textareas or console input you may get some newline characters. One way to remove newline characters is the String#chop method, it will remove any trailing newline or carriage return characters “\r\n”. But it’s tricky. Because here it works like it’s suppose to.

full_name = "My Name is Jared\r\n"  
full_name.chop! # => "My Name is Jared"

Now if you run chop and there are no newline characters.

puts full_name    #=> "My Name is Jared"
full_name.chop!  #=> "My Name is Jare"

Disaster Strikes!

That’s why there is chomp.

puts full_name       #=> "My Name is Jared\r\n"
full_name.chomp!  #=> "My Name is Jared"
full_name.chomp!  #=> "My Name is Jared"

So chomp is our recommended way of removing trailing newline characters.

Test One Cucumber Feature File at a Time

April 10th, 2009 by Chris Gunnels

To most this may sound commonplace. (definition 2).

So I was banging my head for a hour to find out how to test one feature file at a time. If you don’t know how to do this yet then you’ll want to follow along, if you do, then just read another post and make a good comment!

If this sounds like you:

“I have multiple cucumber feature files in the features folder within my app, I want to test one of those files and not all of them at once, but don’t know how.”

Then you’re in for a treat.

Read the rest of this entry »

Interactive Ruby With Tab Completion

April 10th, 2009 by Aaron Murphy

Do you like tab completion with bash? Now you can have it with irb too! Just setup your .bashrc file with an alias so you don’t have to remember the entire command line. It’s not exactly the same as bash. You will have to hit the tab key twice. On my Ubuntu 8.10 system it works as listed below.

Read the rest of this entry »

Yield to the Ruby Master

April 9th, 2009 by justin

After a time of much outer influence and inner struggle, I, a self-proclaimed Microsoft fanboy, decided to abandon everything I’ve known for the last 6 years as a .NET developer and sample the sweet simplicity and sheer power that is Ruby on Rails.

One of the first things I learned while working on my first Rails project was the use of Ruby’s yield statement.  Coming from C#, I expected the yield statement to act a bit differently than it does in Ruby.  Basically, the yield statement is provided as a way to ease the creation of iterators.  It gives control to a user-specified block from within a method’s body.

Read the rest of this entry »


Copyright © 2005-2011 PMA Media Group. All Rights Reserved