Pages

Showing posts with label Agile. Show all posts
Showing posts with label Agile. Show all posts

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

Thursday, 22 July 2010

Java2Word Microsoft Word Document Generator from Java code without any "special" components or libraries

I had a problem in my work a few weeks ago which was how to generate one Microsoft Word Document from Java code. Reports were composite by 40 pages around and over 30 database queries to bring data. It also had cover page, table of contents, header, footer and many tables.

We tried a lot of things but they were all crap solution. We had to delivery those "word" reports so the solution was pretty bad: Generate Jasper RTF and open as an Word Document.

When you open this rtf, the result is just horrible. You can't properly edit those dodge tables generated by jasper. Other problem is when you save this document as .doc, file size increased from 5 MB to 40 MB.

So... there were I again... playing around with the problem...

I decide to create an API in Java to generate Word documents from Java code. The Document generated HAS to be compatible with Microsoft Word and can't have any manipulation - so has to be ready for the end user!

I wrote two implementations: one for Word 97 - 2003 and another for Word 2004 +.

To be honest I spent more time in W2004 because this is the current standard.

I have created the java project and hosted in Google code:

http://code.google.com/p/java2word/

The philosophy is have something in Java and really easy like:

   IDocument myDoc = new Document2004();
myDoc.getBody().addEle(new Heading1("Heading01"));
myDoc.getBody().addEle(new Paragraph("This is a paragraph..."));



You are Java dev and deal with this API. You Don't need to worry about the implementation!

*Project has 97% of code test coverage.

** When I say no "special" components I mean not using any MS library.
In order to use the Java2Word you will need in your classpath xstream (if you use images) and log4j (for other than JBoss server).
Please refer to dependencies section in the project page.


Monday, 5 April 2010

Agile na veia: BDD e TDD.

Estou trabalhando em um projeto na Austrália onde o pessoal adota agile completo com SCRUM, XP, BDD (Business Driven Development) e TDD (Test Driven Development)

Vou escrever esse em portugues porque eu não sei se o pessoal esta usando as mesmas coisas no Brazil. E tambem quero praticar meu portugues já que não falo e nem escrevo em pt_br há bastante tempo.

Ferramentas utilizadas são:

Cucumber: Testes de integração automatizados escritos por QA (quality assurance). Testes são implementados em Ruby e JRuby.

Selenium + Webrat: End-to-end testes totalmente automatizados - acabou aquela época de o tester ficar igual a um macaquinho clicando em todos os links etc...

Agile: stand up meeting todo dia pela manha, Retro meetings no final de cada iteração para discutir o que ocorreu de bom e ruim. É tipo uma lavação de roupa suja por meia hora. Pair programming o tempo todo - eu disse o tempo todo. Nenhum codigo pode ser escrito sem "pair

JBoss ESB: Transformação dos dados e alimentaçao do FAST. A transformaçao é feita usando Smooks e gerando um XML através do Freemaker e entao fornecendo essa XML para armazenamento pelo FAST.

Liquibase: Melhora o controle de mudanças no banco de dados.

MySql: Base de dados de uns 90GB.

FAST ESP: Melhorar performance nas pesquisas e na indexação de documentos. Neste caso FAST e usado como um banco de dados com performance elevada. NÃO ache que documento é um .doc ou .xls. Na minha opinião FAST é um "Elefante branco".

Git: Controle de versoes - tipo SVN.

Hudson: Nosso CI (Continuous integration)

O que eu mais gostei:

Com o pair programming eu aprendi Ruby em um tempo muito reduzido. Tambem aprendi a escrever código curto e fácil de ser testado.

Achei o BDD legal. Outra regra no projeto é: Não se escreve código sem Cucumber test que o justifique. Cucumber testes são escritos no ponto de vista do usuário final e segem todos os critérios de aceitação para aquela implementação. Isso quer dizer que quando você desenvolvedor escreve seu codigo, voce já sabe exatamente o que tem que implementar.

Comunicação constante no stand-up sobre o que voce fez, vai fazer e problemas.
Qualquer pedaço de papel ou rabisco vira documentação.

Também acabou aquela palhaçada de o gerente do projeto ficar enchendo a porra do saco a cada 10 minutos perguntando sobre o andamento da tarefa - é só olhar o card board que está tudo lá (what the fuck???).

Refactoring o tempo todo. Voce se sente seguro em efetuar um refactoring porque o código esta todo coberto por testes unitários.

Trabalhei eu vários projetos onde existiam códigos cheios de gambiarra, ninguém sabia como funcionava e niguém podia alterar nada senao parava de funcionar - eu tinha até medo de tocar naquele código.

Com agile, o codigo fica mais maduro com o passar do tempo porque ele vai ser testado e refatorado centena de vezes.


Abraço a todos!

Leonardo