Hoje irei enfatizar a minha solução para escrever código que manipule pop-ups javascript no Ruby WATIR, observando a discrepância que existe na programação para IE e para Firefox.

Fato: muitas aplicações que realizam processamentos server-side costumam apresentar seus resultados por via de pop-ups javascript (isto é muito comum quando utiliza-se AJAX).

O grande problema que ocorre é que, devido ao modo pelo qual WATIR se comunica com cada browser (IE usa a API do Windows e Firefox usa o plugin JSSH), as maneiras que cada uma destas soluções foram desenvolvidas têm naturezas distintas.

No post anterior 10 boas práticas em Ruby WATIR, a Boa Prática 5 - Isolar a discrepância entre IE e Firefox em métodos polimórficos usando o design pattern Strategy apresenta uma solução para este problema, utilizando um padrão de projeto GoF para favorecer isolamento de código e promover reutilização. Não vou repetir o post aqui, portanto verifique neste post a solução apresentada.

Observe que, ainda assim, mensagens pop-up javascript contendo texto são uma fonte de problemas quando se deseja compatibilidade plena entre IE e Firefox. Isto se dá pois cada browser manipula de forma diferente seus pop-ups, e ainda assim em momentos diferentes!

No post anterior 10 boas práticas em Ruby WATIR, a Boa Prática 7 - Evitar ter de manipular mensagens pop-up javascript enfatiza conseqüências e alternativas para isso.

Resumo

Eu tenho apenas 5 meses de experiência com WATIR, mas já me convenci de certas práticas de utilização que considero boas, e que de alguma forma estão trazendo resultados positivos.

Vale lembrar que são todas baseadas no bom-senso.

 


Conteúdo

  1. Utilizar sempre a interface Watir::Browser
  2. Buscar componentes HTML por id sempre que possível
  3. Extrair dados de entrada/saída e mensagens em constantes
  4. Quebrar a lógica em métodos privados para promover reutilização
  5. Isolar a discrepância entre IE e Firefox em métodos polimórficos usando o design pattern Strategy
  6. Escrever no console mensagens de controle e andamento
  7. Evitar ter de manipular mensagens pop-up javascript
  8. Cuidado com inclusões de páginas
  9. Recuperar mensagens de arquivos de texto
  10. Ao testar inclusões com sucesso, realizar a limpeza depois

 


1. Utilizar sempre a interface Watir::Browser

A partir da versão 1.6.2, foi introduzida a interface Watir::Browser, que veio para permitir o tratamento do browser genericamente, sem fazer referência a um browser específico como antigamente, quando eram instanciados objetos Watir::IE ou FireWatir::Firefox.

É boa prática sempre instanciar objetos Watir::Browser, e deixar a definição de qual browser será utilizado fora de seu código-fonte, ou seja, esta decisão não deve ser hard-coded. Assim, pode-se alterar o browser a ser utilizado sem alterar o código-fonte, alavancando desta forma processos automáticos de execução de testes (como scripts ANT) alterarem o browser a ser testado em tempo de execução.

 

2. Buscar componentes HTML por id sempre que possível

Existem várias maneiras de se localizar um componente HTML em uma página, como se pode ver no link Methods Supported by Element. Cada componente tem vários critérios de localização como id, name, value, text, href, index, xpath, class

No entanto, cada um destes critérios tem um motivo de estar sendo usado – e este motivo pode precisar de flexibilidade.

Por exemplo, o critério name representa o nome deste componente em um formulário, e isto comumente é utilizado para refletir em propriedades de form beans do lado do servidor. Ou seja, pode ser um reflexo de uma lógica de negócio – que PODE MUDAR FACILMENTE!

Outros exemplos:

  • o critério href representa uma URL – que PODE MUDAR FACILMENTE!
  • o critério text representa texto de página – que PODE MUDAR FACILMENTE!
  • o critério value representa o valor padrão de um componente – que PODE MUDAR FACILMENTE!

Todavia, o id não tem motivos para mudar facilmente assim, pois seu propósito é geralmente apenas identificar um componente HTML, o que teoricamente não sofre implicações da lógica de negócio. Portanto, é vantajoso localizar programaticamente por id, sempre que possível.

Se o componente desejado não houver atributo id, criá-lo não causará impacto algum na página (ENTRETANTO, verifique se o id desejado já não foi utilizado em sua página ou em alguma página incluída dela). Recomendação: escolha o id longo, claro e baseado no propósito do componente, de forma a não sobrarem motivos para dar este mesmo id a outro componente.

Ao mesmo tempo, essa prática de utilizar id em todos os componentes promove outro aspecto: melhora a legibilidade do código HTML, identificando cada componente quanto a seu propósito.

 

3. Extrair dados de entrada/saída e mensagens em constantes

Dados de entrada e saída de um teste geralmente não mudam durante sua execução. Nem mensagens  esperadas de sucesso ou falha.

Desta forma, é uma boa prática extraí-los para constantes globais e colocar todos no início do código. Assim ganhamos performance, legibilidade e reuso.

Constantes em Ruby são definidas simplesmente como variáveis que iniciam com letra maiúscula. Aqui no exemplo também começam com $ pois são globais.

Antes:

-------------------- test.rb
# requires
require "test/unit"
require "watir"
require "watir/testcase"

##
# Test case for sign up scenarios
# @author Tiago Romero Garcia
#
class Test < Watir::TestCase

  # Method for setting up a test method
  def setup
    @browser = Watir::Browser.start "http://localhost/myapp/index.jsp"
    @browser.maximize
  end

  # (...)

  # Method for testing sign up
  def test_sign_up

    # (...)       

    # tries to sign up
    @browser.text_field(:id, "emailId").set("test@provider.com")
    @browser.text_field(:id, "passwordId").set("testing")
    @browser.text_field(:id, "confirmPasswordId").set("testing")
    @browser.button(:name, "register").click

    # (...)

    # checks if sign up was successful
    test_condition = @browser.text.include?("Thank you for signing up")
    fail_message = "It should show this message:\n" +
                   "- Thank you for signing up"
    assert(test_condition, fail_message)

    # (...)

  end

  # (...) 

end
-------------------- end of test.rb

Depois:

-------------------- test.rb
# requires
require "test/unit"
require "watir"
require "watir/testcase"

# set variables
$Index_page = "http://localhost/myapp/index.jsp"
$New_email = "test@provider.com"
$New_password = "testing"

# messages
$Success_message = "Thank you for signing up"

# (...)

##
# Test case for sign up scenarios
# @author Tiago Romero Garcia
#
class Test < Watir::TestCase

  # Method for setting up a test method
  def setup
    @browser = Watir::Browser.start $Index_page
    @browser.maximize
  end

  # (...)

  # Method for testing sign up
  def test_sign_up

    # (...)

    # tries to sign up
    @browser.text_field(:id, "emailId").set($New_email)
    @browser.text_field(:id, "passwordId").set($New_password)
    @browser.text_field(:id, "confirmPasswordId").set($New_password)
    @browser.button(:name, "register").click

    # (...)

    # checks if sign up was successful
    test_condition = @browser.text.include?($Success_message)
    fail_message = "It should show this message:\n" +
                   "- " + $Success_message
    assert(test_condition, fail_message)

    # (...)

  end

  # (...)

end
-------------------- end of test.rb

 

4. Quebrar a lógica em métodos privados para promover reutilização

Esta prática é bem conhecida e utilizada em outras plataformas, e aqui não tem nada de novo: é boa prática que o desenvolvedor identifique blocos de código repetitivos, e extraia tais blocos em métodos privados que serão chamados por outros.

Blocos de código repetitivos comuns em scripts WATIR: ação de login, ação de logoff, ação de clicar em um botão ou link e testar se houve sucesso, ação de preencher um determinado formulário e testar se houve sucesso, ação de aceitar a falta de certificado quando estiver usando HTTPS, etc.

Mesmo que inicialmente não haja outros métodos chamando um bloco de código potencialmente repetitivo, ainda pode ser bom extrair para um método por motivos de legibilidade e mantenibilidade do código.

 

5. Isolar a discrepância entre IE e Firefox em métodos polimórficos usando o design pattern Strategy

A versão 1.6.2 introduziu um grau de proximidade nunca antes alcançado entre o código feito para o IE e Firefox. Entretanto, muitos detalhes ainda são dependentes de browser, principalmente devido ao modo pelo qual WATIR se comunica com cada browser (IE usa a API do Windows e Firefox usa o plugin JSSH).

Desta forma, para determinadas operações, teremos que construir código específico de browser, como manipulação de pop-ups e DOM.

Mesmo assim, é possível evitar de, para um mesmo teste, construir um test case para IE e outro para Firefox. A solução é simples: aplicação do design pattern Strategy (Estratégia).

Para isto, basta fazer o seguinte:

  1. Definir a Estratégia: Definir um método polimórfico que invocará a operação específica de browser, que será invocado na classe do test case. Lembre-se que em Ruby não existem interfaces como em Java, portanto para isto funcionar, basta escrever da mesma forma este método polimórfico nas classes que implementarem a Estratégia.
  2. Escrever as Estratégias: Criar as classes que irão conter o código específico de browser, dentro do método polimórfico anteriormente definido (implementação da Estratégia).
  3. Usar a Estratégia: Agora, a classe do test case deverá construir ou receber um objeto de uma classe que implementou a Estragégia. Com este objeto, invocar o método polimórfico ao invés dos trechos de código específico de browser.

Exemplo:

1. Definir a Estratégia: é necessário um método para clicar em um botão que exibirá um popup em javascript, e checar se este popup possui uma determinada mensagem. Nosso método será:

clickAndCheckPopup(message)

2. Escrever as Estratégias: escreveremos 2 classes para manipular código específico, uma para IE e outra para Firefox:

-------------------- ie_handler.rb
require "Win32API"
require 'dl/import'
require 'dl/struct'
require "watir/win32"
require "watir/contrib/enabled_popup"

##
# Handler for IE-specific code (strategy design pattern).
# Its goal is to promove independency to test cases.
# They shall not know particularities from browsers.
#
# @author Tiago Romero Garcia
#
class IEHandler

private

  # Method for investigating a popup
  def popup_checker(button_text, message, waitTime=9)
    # get a handle if one exists
    hwnd = @browser.enabled_popup(waitTime)
    if (hwnd)  # yes there is a popup
      w = WinClicker.new

      # I put this in to see the text being input it is not necessary
      # to work "OK" or whatever the name on the button is
      test_condition = w.getStaticText_hWnd(hwnd).include?(message)
      w.clickWindowsButton_hwnd( hwnd, "#{button_text}" )

      # this is just cleanup
      w=nil    

      return test_condition
    end
  end

public

  def initialize(browser)
    @browser = browser
  end

  def clickAndCheckPopup(message)
    @browser.button(:id, "myButtonId").click_no_wait
    puts "Clicked on my button"

    popup_checker("OK", message, 7)
  end    

end
-------------------- end of ie_handler.rb

-------------------- firefox_handler.rb
require "test/unit"

##
# Handler for Firefox-specific code (strategy design pattern).
# Its goal is to promove independency to test cases.
# They shall not know particularities from browsers.
#
# @author Tiago Romero Garcia
#
class FirefoxHandler

public

  def initialize(browser)
    @browser = browser
  end

  def clickAndCheckPopup(message)
    @browser.startClicker("OK")
    @browser.button(:id, "myButtonId").click
    puts "Clicked on my button"

    popupText = @browser.get_popup_text
    popupText.include?(message)
  end    

end
-------------------- end of firefox_handler.rb

3. Usar a Estratégia: a classe do test case ficará assim:

# requires
require "test/unit"
require "watir"
require "watir/testcase"
require "tests/extras/ie_handler"
require "tests/extras/firefox_handler"

# set variables
$Index_page = "http://localhost/jsp/index.jsp"

$Success_message= "Sucessfully operation!"

##
# My test case
# @author Tiago Romero Garcia
#
class MyTest < Watir::TestCase

# Define private methods
private    

  # Method for setting up a test method
  def setup
    puts "------------------------------------------------------------"
    @browser = Watir::Browser.start $Index_page
    @browser.maximize

    if @browser.kind_of?Watir::IE
      @browser_handler = IEHandler.new @browser
    else
      @browser_handler = FirefoxHandler.new @browser
    end
  end

  # Method for tearing down a test method
  def teardown
    @browser.close
  end

  # (...)  

# Define public methods
public      

  # Method for testing my stuff
  def test_my_stuff
    puts "TEST METHOD BEGIN - My stuff"

    # (...)

    test_condition = @browser_handler.clickAndCheckPopup $Success_msg
    fail_message = "It should show this string:" +
                   "\n-" + $Success_msg
    assert(test_condition, fail_message)    

    # (...)

    puts "TEST METHOD END WITH SUCCESS - My stuff"
  end

  # (...)

end

 

6. Escrever no console mensagens de controle e andamento

Geralmente, para todo processo em lote é interessante exibir mensagens de controle e andamento (log). As principais vantagens dessa prática são:

  • Em caso de erro, saber qual o ponto da execução que originou o problema.
  • Ter mais detalhes ao acompanhar a execução do processo “ao vivo”.
  • Documentar todos os passos do processo.

Portanto, é boa prática escrever no console mensagens de texto detalhando o que acabou de ser feito. Isto é especialmente útil após ações como: carregar uma página, clicar em botão ou link, enviar formulário, escolher dentre uma lista de seleção, etc.


7. Evitar ter de manipular mensagens pop-up javascript

Mensagens pop-up javascript contendo texto são uma fonte de problemas, quando se deseja compatibilidade plena entre IE e Firefox. Isto se dá pois cada browser manipula de forma diferente seus pop-ups, e ainda assim em momentos diferentes!

Por exemplo, na boa prática n° 5, o código para IE dentro de ie_handler.rb executa um programa externo ao browser que será um listener de pop-ups javascript. Possui uma vantagem: consegue capturar pop-ups mesmo que o browser mude de página.

Já o trecho para Firefox dentro de firefox_handler.rb realiza o listening dentro do código. Este não consegue capturar pop-ups se o browser mudar de página.

A boa prática aqui é evitar o máximo possível de se usar este critério para avaliar os resultados de um teste. Em caso de ser uma mensagem revelando o resultado de algum processamento, verifique se após este processamento a página sofrerá alguma alteração. Se sofrer, ao invés de avaliar a mensagem do pop-up, pode-se avaliar se a página sofreu tal alteração.


8. Cuidado com inclusões de páginas

Sites programados em linguagens de scripting server-side como JSP e PHP permitem a inclusão de páginas em outras. Esta é uma prática muito utilizada, especialmente para a reutilização de trechos estáticos do site como menu, cabeçalho e rodapé.

Entretanto, isto pode bagunçar demais a cabeça do programador WATIR, pois pode ser que alguma página incluída tenha tags com as mesmas características que tags na página que as inclui. Assim, ao procurar por tags na página, pode ser que WATIR encontre primeiro tags das páginas incluídas! 

As boas práticas para evitar este problema são:

  • Quando lidar com páginas que incluam outras páginas, verifique o HTML gerado no browser se a tag que você quer achar será realmente identificada pelo critério que você escolheu. Exiba o código-fonte do browser e faça uma busca no texto para ver se não encontra outras tags com o mesmo critério.
  • Escreva tags com ids realmente “identificadores”, ou seja, que descrevam realmente o propósito da tag, mesmo que seja um nome longo. Por exemplo, ao invés de fazer
    <input type="text" id="name">

    prefira fazer

    <input type="text" id="signupFormName">

    Assim, você reduz a chance de acontecerem problemas assim.

 

9. Recuperar mensagens de arquivos de texto

Aplicações web podem recuperar mensagens de arquivos de texto ou arquivos properties, principalmente quando utiliza-se internacionalização (i18n). Quando for este caso, é uma boa prática recuperar as mensagens diretamente destes arquivos, e não escrevê-las novamente na classe de teste. Quanto menos hard-coded puderem ser as mensagens, melhor!

Eu utilizo para isto a seguinte classe leitora de arquivos properties de java, disponível neste link. Agradeço a Devender Gollapally por permitir a reprodução e utilização de seu código aqui.

-------------------- java_props.rb
#
# Class for handling java-style properties files
# Author: Devender Gollapally
# From: http://devender.wordpress.com/2006/05/01/reading-and-writing-
java-property-files-with-ruby/
#
class JavaProps
  attr_reader :file, :properties

  #Takes a file and loads the properties in that file
  def initialize file
    @file = file
    @properties = {}
    IO.foreach(file) do |line|
      @properties[$1.strip] = $2
          if line =~ /([^=]*)=(.*)\/\/(.*)/ || line =~ /([^=]*)=(.*)/
    end
  end

  #Helpfull to string
  def to_s
    output = "File Name #{@file} \n"
    @properties.each {|key,value| output += " #{key}= #{value} \n" }
    output
  end

  #Write a property
  def write_property (key,value)
    @properties[key] = value
  end

  #Save the properties back to file
  def save
    file = File.new(@file,"w+")
    @properties.each {|key,value| file.puts " #{key}= #{value} \n" }
  end

end
-------------------- end of java_props.rb

 

10. Ao testar inclusões com sucesso, realizar a limpeza depois

Quando é necessário testar uma página de inclusão, o fluxo principal deve ser testado, ou seja, uma inclusão deve ser feita com sucesso. Geralmente são utilizados dados de teste para isto.

Isto tem uma contrapartida: os dados ficam armazenados no banco de dados, e isto representa lixo. Quanto mais vezes o teste for executado, mais lixo será gerado e assim vai…

O ideal é que seja realizada uma limpeza imediatamente após o sucesso do teste. Deve ser projetada uma maneira segura para isto, que não coloque a integridade dos dados em risco.

Uma possibilidade para isto é construir um processo de negócio para essa limpeza, e disponibilizar uma URL que delegue a chamada a este processo de negócio. Em uma arquitetura Java EE, o processo de negócio pode ser um método de um EJB, ou um serviço de um BusinessObject; e a URL pode chamar um servlet que invoque tal EJB ou BusinessObject.

Sugiro as seguintes etapas:

  • Passagem por parâmetro da URL do identificador do dado recém-incluído
  • Autenticação do usuário de teste (ou do cliente que estiver chamando a URL)
  • Deleção do dado recém-incluído baseado no identificador

Resumo

Quem pretende utilizar Watir para testar sistemas desenvolvidos em Java EE pode comemorar! É possível ter um ambiente de desenvolvimento baseado em Java e Ruby, e melhor ainda, rodando testes Watir da mesma forma que testes JUnit!

 


Conteúdo

  1. RDT
  2. Instalação
  3. Utilização
  4. Problemas conhecidos

 


1. RDT

Hoje apresentarei o ambiente Ruby Development Tools (RDT), baseado no Eclipse. RDT é um ambiente de desenvolvimento em Ruby, possui debugger Ruby, invocador de Test::Unit, invocador de aplicações em Ruby, syntax highlighting, completador de código (nosso famoso ctrl+espaço), folding, refactoring, etc.

 

2. Instalação

Uma maneira de instalá-lo é diretamente no Eclipse > Help > Software Updates > Find and Install > Search for new features radio button > next > new remote Site. Configure Name = Ruby e URL = http://rubyeclipse.sf.net/updatesite

Outra maneira é utilizar os instaladores do EasyEclipse, conforme explicado no post anterior Ruby WATIR.

Após instalar, você deverá configurar o caminho correto para seu interpretador Ruby em Window > Preferences > Ruby > Installed interpreters. Navegue e configure para algum caminho como c:\ruby\bin\ruby.exe

Pronto! Agora crie um Ruby project e comece a brincar!

 

3. Utilização

Para utilizar a ferramenta de teste: dentro de um Ruby Project, crie um test case em Watir (como uma classe Ruby herdando de Watir::TestCase ou Test::Unit::TestCase), clique com o botão direito do mouse em cima do arquivo rb > Run As > Test::Unit Test.

Para quem não sabe a principal diferença entre estas classes, saiba que Watir::TestCase executa os métodos teste na ordem em que estão dispostos na classe, e Test::Unit::TestCase os executa em ordem alfabética.

Um método teste deve começar com test, por exemplo:

  def test_login_unsuccessful_due_to_no_email
    # (...)
  end

Se houver um método setup, será executado antes de cada método teste. Igualmente com método teardown após cada método teste.

Faça alguns testes, e observe que realmente é um plugin muito eficiente e produtivo.

 

4. Problemas conhecidos

Um problema que costumo enfrentar, após diversos testes, é aparecer um erro ao tentar executar scripts para Firefox. A mensagem de erro diz que não consegue achar o método nil::close (onde seria uma chamada @browser.close).

Problemas assim vêm de alguma falha de comunicação com o plugin JSSh do Firefox, e a solução é simples: reiniciar o Firefox. Eu demorei a achar esta solução, pois uso meu Firefox com Gmail aberto o tempo todo, muitas vezes fica o dia todo aberto, e custou pra eu pensar em fechá-lo… :P

Outra coisa que acontece algumas vezes é, em test cases para IE com vários métodos teste, acontecer uma enorme demora em algum ponto do script. Sobre este problema, infelizmente, não consegui fazer nada para solucionar. Quem tiver alguma idéia, por favor sinta-se à vontade para contribuir! :)

Resumo

Em sua nova versão 1.6.2, Watir uniu-se ao projeto FireWatir e ambos agora estão sob desenvolvimento da mesma equipe. Entre as principais novidades, temos agora a interface Watir::Browser, que introduz polimorfismo entre as APIs de diferentes browsers. Foi um grande salto! :)

 


Conteúdo

  1. Instalação
  2. Interface Browser
  3. Considerações

 


1. Instalação

Se você já tem Watir instalado, para obter a nova versão, digite o seguinte no prompt de comando:

gem update
gem clean

Assim, você atualizará seus gems e removerá suas respectivas versões antigas.

Se não possui, instale normalmente seguindo o post anterior Ruby WATIR.

Possivelmente em suas execuções você poderá encontrar exceções parecidas com

Exception 'WIN32OLERuntimeError' at <filename.rb>:<line#> -
    unknown OLE server: 'AutoItX3.Control'

como foi meu caso. Para solucionar isto, é necessário registrar novamente a dll AutoItX3.dll, que é componente de Watir. Isto deve ser feito no diretório em que se encontra.

Para isto, assumindo que o diretório de instalação é c:\ruby, abra o prompt de comando e digite o seguinte:

cd c:\ruby\lib\ruby\gems\1.8\gems\watir-1.6.2\lib\watir
regsvr32 AutoItX3.dll

Você deverá ver uma janelinha pop-up dizendo “DllRegisterServer in autoitx3.dll succeeded”. Este procedimento está descrito no FAQ de Watir.

 

2. Interface Browser

A primeira grande vantagem desta nova versão é a interface Browser. Utilizando a mesma, agora o objeto que comunica com o browser não será mais inicializado como Watir::IE.new ou FireWatir::Firefox.new, mas sim como Watir::Browser.new. Isto promove um código mais independente de qual browser será utilizado, possibilitando que a escolha do browser não seja mais hard-coded.

A decisão de qual browser será utilizado pode ser feita de três maneiras:

a) Variável de ambiente

Utilize a instrução abaixo ANTES de fazer a chamada Watir::Browser.new, com os valores ie ou firefox:

set watir_browser=firefox

b) Atributo Watir::Browser.default

Utilize a instrução abaixo ANTES de fazer a chamada Watir::Browser.new, com os valores ‘ie’ ou ‘firefox’:

Watir::Browser.default = 'firefox'

c) Arquivo de configuração

Crie um arquivo chamado options.yml com o seguinte conteúdo:

# This file specifies options affecting the unit tests.
# You need to copy this file to "options.yml" before it to work.

# These options can also be set using environment variables prefixed
# with 'watir_'.
# These environment variables will override settings from this file.

# 'ie' (Watir::IE) or 'firefox' (FireWatir::Firefox)
browser: firefox

# These options only affect IE.
# speed options are fast, slow, and zippy
speed: fast
visible: true

Agora, referencie este arquivo em sua classe desta maneira (utilizar caminho absoluto), novamente ANTES de fazer a chamada Watir::Browser.new:

Watir.options_file = "c:/.../options.yml"

O IE possui as propriedades particulares :speed e :visible. Ambas funcionam para as chamadas Browser.new and Browser.start.

Já o FireFox possui as propriedade :waitTime e :profile. Ambas funcionam apenas para a chamada Browser.new.

 

3. Considerações

Na minha opinião, infelizmente o gem ainda não está maduro o suficiente para suportar o mesmo código tanto para IE quanto para Firefox, a nível de produção. Para pequenas tarefas isto já é possível, mas quando é preciso envolver tarefas como manipulação de pop-ups, já começam a aparecer incompatibilidades.

Entretanto, Watir está evoluindo muito depressa e acredito que logo teremos tal maturidade. Verificando códigos beta da equipe de desenvolvimento, já vi funcionalidades bacana de tagging para os métodos de teste, onde, por exemplo, é possível especificar que um determinado método não funciona no IE, e mais tarde é possível esquivar tal método da execução, se no arquivo options.yml estiver configurado para IE.

Quem executar scripts com a mesma finalidade em Watir e FireWatir vai logo perceber que FireWatir é BEEEEM mais rápido que Watir… Dependendo, ao construir um Test Case com vários métodos teste, essa diferença se torna bem incômoda no Watir.

Para quem não sabe, Watir e FireWatir trabalham em cima de um objeto que representará o browser utilizado, e este objeto possui métodos para acessar todos os elementos de uma página HTML, além de eventuais configurações.

Veja aqui um resumo destes métodos para Watir

Para fazer Watir executar com maior velocidade, chame o seguinte método após a inicialização de seu objeto browser (no exemplo abaixo ele se chama ie):

  @ie.set_fast_speed

De forma que um início de test case em Watir pode ser configurado assim:

# requires
require "test/unit"
require "watir"
require "watir/testcase"

# Classe test case em Watir
# autor: Tiago Romero Garcia
class MeuTeste < Watir::TestCase

  # Método que define configurações iniciais antes de cada método teste
  def setup
    @ie = Watir::IE.new
    @ie.bring_to_front
    @ie.maximize
    @ie.set_fast_speed
  end

  # Método que define configurações finais após cada método teste
  def teardown
    @ie.close
  end

  # Métodos teste
  # (...)

end

A API do Watir é bem auto-explicativa e bem simples de entender. Adivinha o que os métodos abaixo fazem? Quem acertar ganha um doce:

  @ie.bring_to_front
  @ie.maximize

FireWatir não precisa de métodos para funcionar mais rápido :)
Um início de test case em FireWatir pode ser configurado assim:

# requires
require "test/unit"
require "firewatir"
require "watir/testcase"

# Classe test case em FireWatir
# autor: Tiago Romero Garcia
class MeuTeste < Watir::TestCase

  # Método que define configurações iniciais antes de cada método teste
  def setup
    @ff = FireWatir::Firefox.new
    @ff.maximize
  end

  # Método que define configurações finais após cada método teste
  def teardown
    @ff.close
  end

  # Métodos teste
  # (...)

end

No próximo post mostrarei como executar Test Cases de Watir / Firewatir dentro do Eclipse através do plugin RubyEclipse. Eles executam de maneira idêntica ao JUnit!

O framework Watir, projetado para o uso com o browser Internet Explorer, assumiu ser incendiado pelo rabo da raposinha e cada vez mais esforços vêm sendo feitos para fornecer um framework integrado para automação de testes em páginas web através do browser Mozilla Firefox.

FireWatir é um gem no Ruby que atualmente se coloca paralelamente ao Watir, apesar de que seus desenvolvedores estão mesclando ambos sob uma única API. Atualmente, existem algumas divergência entre ambos, de forma que não é seguro reaproveitar completamente o código de um no outro. No projeto em que trabalho, tivemos todos os test cases para Watir copiados e adaptados para FireWatir, de forma que a manutenção em um teste deve ser duplicada pra que ambos frameworks apresentem os mesmos resultados.

Apesar disso, suas APIs são bastante similares, mas conheça suas principais diferenças.

Achei sua execução bem mais rápida do que no IE, e alguns detalhes em sua API tentam ser um pouco mais simples que Watir (e menos gambiarrentos), por exemplo a manipulação de popups.

Para instalar FireWatir faça o seguinte:

a) Instale FireWatir Gem

No prompt de comando digite:

gem install firewatir

b) Instale JSSH Firefox Extension

Plataforma Firefox 2.x Firefox 3.x
Windows instalar instalar
Mac instalar instalar
Linux instalar instalar

 

c) Altere configurações no Firefox

c1) Habilite os pop ups. Você pode permitir todos os pop ups ou apenas os provenientes de determinados sites que você estiver testando.

c2) Configure para Firefox abrir uma nova janela ao invés de uma nova aba quando um link é clicado.

d) Execute os testes de FireWatir

Para uma instalação Windows vá em C:\ruby\lib\ruby\gems\1.8\gems\firewatir-1.2.1\unittests e execute mozilla_all_tests.rb

Fonte: http://wiki.openqa.org/display/WTR/FireWatir#FireWatir-Installation

Apesar de sua imaturidade, estou satisfeito com FireWatir, e acredito que sua união com Watir irá melhorar ambos.

Em meu próximo post mostrarei como eu desenvolvo test cases em Watir / FireWatir e colocarei alguns códigos de exemplo.

Inté!

No meu emprego atual, estou trabalhando no projeto Favorpals. É uma rede social que impulsiona um sistema de trocas de favores e/ou bens sem o emprego do dinheiro. Já está funcionando em versão beta, experimente cadastrar um pedido de troca de favores :)

A propósito, lançamos um Gorilla marketing através deste vídeo no Youtube, quem puder visitar e votar 5 estrelas eu agradeço! :)

Ruby WATIR
Ruby WATIR

Well, para este projeto utilizamos o framework Ruby WATIR para a automação de testes funcionais sobre uma interface web utilizando o browser Internet Explorer (existem alternativas para Mozilla Firefox e Safari). É um trem sinistro! Estou gostando bastante de trabalhar com ele.

WATIR significa “Web Application Testing in Ruby”. É uma ferramenta nova porém ótima, fácil de aprender, muito produtiva e em forte ascensão. Na realidade, WATIR é um robô que executa programaticamente interações com um browser da mesma maneira que as pessoas interagem. Ele clica em links, preenche campos, pressiona botões, checa resultados e muito mais.

WATIR é feito em Ruby, que é uma linguagem open source focada em alta produtividade e simplicidade. Confesso que me espantei com suas promessas de produtividade, e nota-se bem que está ganhando cada vez mais força no mercado de trabalho de TI do mundo inteiro.

Programadores Java que desejarem aprender Ruby por favor visitem esta página. É um guia rápido para se aprender Ruby – embora eles mesmo condenem que esta não deve ser uma referência para a linguagem, eu a considero a maneira mais rápida de aprender Ruby para utilização simples como WATIR :) Afinal, escrever testes funcionais não costuma envolver programação pesada.

Vou apresentar um roteiro de como utilizar WATIR em um ambiente de produção Java utilizando Eclipse:

a) Faça o download e instale Ruby

URL: http://rubyforge.org/frs/download.php/29263/ruby186-26.exe

b) Instale WATIR

Para isso, abra um command prompt e digite:

gem update --system
gem install watir
gem update

c) Instale o plugin RubyEclipse.

Este plugin contém um editor de Ruby, que permite rodar Ruby dentro do Eclipse. Mais que isso, ele possui diálogos e wizards para realizar os Unit Tests, exatamente da mesma forma que JUnit. Realmente é admirável. URL: http://www.easyeclipse.org/site/plugins/rubyeclipse.html

Reinicie o Eclipse após intalar este plugin. Ele foi projetado para EasyEclipse, mas pode ser utilizado no Eclipse normalmente.

Voi-lá, seu ambiente está configurado! Teste seu ambiente com este teste exemplo e experimente rodá-lo usando RubyEclipse conforme explicado aqui.

Siga WATIR Tutorial para aprender rapidamente suas funcionalidades. Não tem nada de complicado!

Quem quiser trocar idéias a respeito de Ruby WATIR, por favor entre em contato, será ótimo conversar sobre isto! Quem quiser conhecer mais de perto eu posso mostrar alguns códigos que tenho feito.