Pages

Tuesday 7 December 2010

Mobile Web Sites BDD Cucumber Capybara Gizmo

Have you ever thought about running Cucumber tests for Mobile Web Sites?

Background about my current role:

I have been working as a Mobile Developer. I build web page to run in mobile devices. They could be iPhone, iPad, T-Touch, T-Hub, Galaxy, Nokia, Motorola or any mobile device that can access internet via somehow.


First of all:
  • what is a Mobile Web Site?
It is a site that runs on smart phones, tablets or handsets.

  • what is NOT a Mobile Web Site (in this blog)?
I am not talking about iPhones or Android Apps. If you have one Nokia Mobile you can't install any apple app. 


More about Mobile Web Site here:  http://en.wikipedia.org/wiki/Mobile_Web 




The Funny Challenging

If we have a traditional Web Site we now already how to test it.
We could use Cucumber + Capybara + Gizmo + Selenium Web Driver and run this on the Continouns Integration Server (CI).

We could have in our CI, at least those three different virtual machines: One with in Firefox + Linux, other with Firefox + Windows and last with Windows + Internet Explorer. 

You could consider IE6, IE7, Vista, Windows Seven... anyway this is just an illustration.

How about Mobiles????????????????????????????
Can we run automatic Cucumber tests natively on a Mobile device???????

Additional information: In my work, there are one list of twenty mobile devices that we support. Those devices can be classified as the screen size such as tiny, small, medium, large, extra-large and maybe huge.

The application gives a different CSS configuration per device, but the content by itself is basically the same in most cases. Mobiles from a specific carrier (Eg.: Telstra) could have additional content available.  

Not enough, other devices don't accept cookies. Example of those are some dodge Nokias that surprisingly come up at the tip of the list, according to the corporate stats. This non-cookie devices we have to use URL rewriting .

Every time we have a release, QA guys have to test the application in many different devices. Regarding to mobile, we need to see the font size, if images are visible, text in the write place, etc. In other words, for 20 different devices, possibly 20 different pages.

I am not even talking about HTML5 neither Web Semantic - not also about table-less approach. All those issues would deserve another post and we surely take care of them in my workplace.

Despite of those issues, I think we still can test a lot of things automatically via Cucumber. Using a normal PC web browser, we can definitely test at least 70% of the application.

Certainly we could perform a complete functional test using Cucumber, and finally, by the time  that QA guys take the manual  tests using handset, there will be no more basic functional errors.


How can we emulate a mobile device using Firefox?

I figured it out a way to do this changing Firefox HTTP request headers. This way, the application will respond the request the same way it does for a real device.

I will assume that you have your Cucumber + Capybara environment up and running.

If not, follow these steps:
  • Read this page https://github.com/icaruswings/gizmo
  • git clone https://github.com/icaruswings/gizmo.git
  • Now you have got a Cubumber + Capybara + Gizmo environment half way done.
Now you need to install all gems. I use bundle but if you want something quickly up and running, install the following gems:

  • sudo gem install cucumber
  • sudo gem install rspec
  • sudo gem install gizmo
  • sudo gem install capybara
  • sudo gem install tilt

Now you can run:
  • cucumber features/github_example.feature
This should start Firefox and successfully run the feature.


If you are on Linux Ubuntu 10.10 and see some problem like: spec/specification, run:
  • sudo apt-get install librspec-ruby1.8



Finally The Cool Point of this Post

* Assuming that Cucumber + Capybara is up and running. 

Your env.rb has got a line like this:


Capybara.default_driver = :selenium


I will write my env.rb and how I override Firefox headers using a Firefox Profile. I removed this line and added:

Capybara.default_driver = :selenium_iphone
Capybara.register_driver :selenium_iphone do |app| 
  require 'selenium-webdriver'
  profile = Selenium::WebDriver::Firefox::Profile.new

  profile['general.user


.override'] = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7"
  profile['general.description.override'] = "Mozilla" # appCodeName
  profile['general.appname.override'] = "Netscape"
  profile['general.appversion.override'] = "5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7"
  profile['general.platform.override'] = "iPhone"
  profile['general.useragent.vendor'] = "Apple Computer, Inc."
  profile['general.useragent.vendorSub'] = ""

  Capybara::Driver::Selenium.new(app, :profile => profile)

end



This is my spike feature:

Feature:
    As a Mobile Developer
    In want to have a DRY, elegant and maintainable tests for all diferent devices
    So that I can to simulate mobile (hi-end and low-end) and desktop browsers 

    @iphone
    Scenario: It opens the test page and shows which browser is being simulated
        Given a user is on the user-agent-switcher homepage



This is the implementation of the one and only one step:

Given /^a user is on the user\-agent\-switcher homepage$/ do        
  visit "http://chrispederick.com/work/user-agent-switcher/features/test/" 
  sleep 15 # so that I can see the new values
end


At this point I would recommend you to take a look at the Firefox Plugin and web page User Agent Switcher: http://chrispederick.com/work/user-agent-switcher/features/test/



In addition, you can enable and disable cookies. Why? If some developer forget to use URL rewriting (JSTL: ), you can catch this in your tests. Disable cookies with this code:

  if ENV["disable_cookies"]  #or variable or whatever...
    puts "_________________ Cookies have been Disabled...."
    profile['network.cookie.cookieBehavior'] = 2 #0 enables, 2 disable all
  end


This is all spike code and you should get those snippets and fit in your test implementation.


I am happy to hear your experience! Feel free to write back with your thoughts and suggestions.

If you are a Mobile Dev and would like to say how you do integration tests or how you do Agile or whatever, leave a comment.


* Curiosities:
  • Capybara creator jnicklas said that wasn't possible to change request headers via Capybara. I found a workaround and did via Selenium Profile. Then I asked him again and He told de me how to do it (Imagine if I had given up with the first answer...). He said that didn't know that was possible to do this workaround...  Thanks jnicklas!!!
  • I almost forgot to sleep one night because the problem was quite interesting...
  • I don't know how to format code in this blog, or how to add code block... shame on me...


cheers

Leonardo Correa

1 comment:

  1. Hi Leonardo!
    Very nice post. Thanks! I am curious if we can explore this on actual emulators. For Ex: Running web application on Android's default browser. I found http://www.youtube.com/watch?v=aj0zbydLvcg on youtube but that has been driven through Junit. I am looking for something BDD using either Cukes or Calabash.

    Any thoughts?
    Thanks!

    ReplyDelete