sexta-feira, 28 de janeiro de 2011

Data Driven com Selenium IDE? Sim, é possível!!!

Selenium IDE com Data Driven? Sim, isto agora é possível!

Observações iniciais
Eu sempre tive uma postura de um profisisonal, quando em aprendizado do Selenium, aprender o IDE a fins educativos e de primeiro passo da automação (record & play), de usar e propor aos profissionais e alunos que me procuram a usar o Selenium RC para fazer testes que exigem bem mais do que o IDE: loops, controles, parametrização de dados, etc...
Mas desta vez resolvi postar sobre como fazer com que o Selenium IDE execute scrips Data Driven


ATENÇÃO: Este post é uma alteração do post original da SauceLabs [1] que você pode acessar no link abaixo:
http://saucelabs.com/blog/index.php/2011/01/selenium-resources-for-newbs-data-driven-testing-with-ide-xml/


Ainda mantenho fortemente a minha postura: usem o Selenium RC com qualquer linguagem para usar todo o poder que essa ferramenta pode te dar. Um dos principais motivos de escrever este post é de:
  • Eu gostar destas coisas novas e ficar brincando com os scripts
  • De ajudar os nossos amigos profissionais que ainda não sabem falar inglês e não poderiam entender o post origianl (e que devem levar um puxão de orelha por isso)
  • Para poder ajudar aqueles que estão aprendendo o Selenium IDE que, mesmo que este post te ajude, não vai poder fugir da programação para fazer coisas mais poderosas com a ferramenta
      
    [1] Pra quem não sabe o criador da SouceLabs, que presta serviços de teste com Selenium nas nuvens, é um dos criadores do Selenium.

    Ahh, e pra quem não sabe o que é Data Driven, é o "poder" de dar ao script a independência de dados através de parâmetros inseridos ao invés dos dados. Se você ainda não sabe o que é isso, Google!


    O que você vai precisar!
    Basicamente de um plugin e duas "user-extensions" do para o Selenium IDE.
    Primeiro siga estes passos:
    1. Instale o plugin de Flow Control. Necessita de reinicio do Firefox
    2. Baixe a user-extension includeCommand4IDE na versão 1.1
    3. Baixe a user-extension datadriven.js, que está na versão 0.2
    Clique nos links de cada item para baixá-lo!
    Instalou o Flow Control e baixou as duas user-extensions? Faça o seguinte:
    1. Descompacte os arquivos zip das respectivas user-extensions num diretório de sua escolha
    2. Adicione as duas user-extensions no Selenium IDE via menu Options/Options... clicando no botão browser para o item Selenium Core extensions (user-extension.js) (vide Possíveis Erros #1)
    3. Reinicie o Selenium IDE
    Deu tudo certo? Maravilha!!! Vamos para os próximos passos!!!


    Criar o arquivo XML de Massa de Dados!
    Sim, para que seja possível fazer com que o script Selenese (script HTML do Selenium) esteja preparado para o Data Driven é necessário criar um arquivo XML que vai conter os dados que tu vais utilizar!

    Uma coisa muito importante é primeiro entender o arquivo XML!

    Entendendo o arquivo XML
    Abaixo está um exemplo do arquivo XML que estou usando:










    A linha 1 possui a tag testdata. É ela que identifica que o arquivo XML é a tua massa de dados.

    As linhas 2, 3 , 4 e 5 possuem a tag test. Cada tag test é um indício de massa de dados que tu vais utilizar no script. Dentro desta tag existem atributos. No exemplo acima os atributos são nome e sobrenome. Estes atributos serão os parâmetros do teu script do Selenium, que irão no formato ${nomeAtributo}.
    Neste caso eu tenho que colocar no meu script os parâmetros ${nome} e ${sobrenome} sem precisar cria-los anteriormente no script.

    A linha 6 fecha a tag do testdata

    Cada atributo tem um valor e é este valor que vai ser substituido pelo parâmetro no script. Lindo né?

    Tu podes criar diversos test um para cada iteração do script que tu necessitar.

    Agora aconselho fortemente ler os itens #2, #3 e #4 do "Possiveis Erros"



    Script!! (êeeeee)
    Agora veremos o script final sobre o exemplo e todos os comandos necessários para que ele funcione!

    loadTestDatafile:///C:/selenium_datadriven/massa_dados.xml
    open/arquivos_blog/selenium/datadriven/
    while!testdata.EOF()
    nextTestData
    typenomePessoa${nome}
    typesobrenomePessoa${sobrenome}
    clickAndWaitsend
    assertTextPresentOlá, ${nome} ${sobrenome}
    clickAndWaitlink=Voltar
    endWhile

    Na linha 1 da tabela temos o comando que fará o carregamento da massa de dados com o comando loadTestData. Este comando é parte da user-extension datadriven.js.
    Você obrigatoriamente deve iniciar o valor deste comando com 'file:///' (sem as aspas simples) seguido pelo caminho do arquivo XML (como no exemplo)

    Na linha 2 da tabela temos o velho conhecido comando open para a minha página de exemplo deste post

    Na linha 3 da tabela temos o comando while, da user-extension FlowControl, que é responsável de fazer um loop no script. O valor deste comando é !testData.EOF() que traduzindo quer dizer: "enquanto o testData não terminar, ou seja, existam as tags test, execute". Ele que é responsável por controlar o número de execuções a partir das tags test existentes.

    Na linha 4 da tabela existe o comando nextTestData que pertence a user-extension datadriven.js. É ela que validará que existam dados na massa de dados (arquivos XML para continuar executando o script)

    Naz linhas 5, 6, 7, 8 e 9 existem os comandos básicos do Selenium para a interação com o exemplo. Aqui tu precisas prestar muita atenção: ao invés de manter os valores fixos no script eu os substitui pelos parâmetro ${nome} e ${sobrenome}, que são os nomes dos atributos da tag test do XML da massa de dados, ententeu? É só colocar o mesmo nome e, acredite, ele preencherá com o valor.

    Na linha 10 da tabela há a finalização do loop pelo comando endWhile que pertence a user-extension FlowControl.


    Agora é só correr para o abraço!!!
    Pronto, tudo está pronto para execução com sucesso!!!
    Tu podes baixar o este exemplo por este link e testar ai!

    Se tu executares o exemplo que tu acabou de baixar, lembre-se de colocar na Base URL o endereço http://eliasnogueira.com

    Agora vamos falar sobre o exemplo:

    Exemplo utilizado!
    O exemplo é bem simples: consiste em um formulário de submissão de dados contendo o Nome e Sobrenome de uma pessoa. Após a submissão dos dados somos redirecionados para uma tela com a seguinte mensagem na página "Olá Fulano de Tal", onde Fulano é o nome e de Tal é o sobrenome inserido!

    A página do exemplo pode ser acessada no link abaixo:
    http://eliasnogueira.com/arquivos_blog/selenium/datadriven/index.php

    Observação: cuidado para este item não te confundir, mas se tu for criar um script sobre uma página ajax ou não quer clicar em algum link de voltar, utilize o comando goBackAndWait antes do comando endWhile. Este comando fará com que o script emule o "voltar" do browser.


    Possíveis Erros
    1. Se você não colocar as extensões no lugar certo receberá a seguinte mensagem logo que abrir o Seleium IDE: "error loading Selenium IDE extensions: ReferenceError: Selenium is not defined". Então garanta que você colocou no campo certo (olhe a imagem)
    2. Elias, posso mudar o nome da tag testdata? Resposta: não!!! Sem esta tag o script não roda, é obrigatória!
    3. Elias, posso mudar o nome da tag test? Resposta: não!!! Sem esta tag o script não roda, é obrigatória!
    4. Elias, posso utilizar parâmetros diferentes entre os testes? Resposta: Sim! desde que os parâmetros obrigatórios estejam la. Se tu não entendeu, deixe todos iguais e o script vai rodar sem erros!

    Problemas com Firefox 20
    Para quem atualizar o Firefox para a versão 20 e estiver usando este modelo de Data Driven no Selenium IDE o seguinte erro será apresentado sempre que o Selenium IDE for aberto:

    Solução
    • Com o Selenium IDE fechado abra com um editor de texto o arquivo datadriven.js
    • Localize o seguinte trecho no arquivo:
    • Acima do trecho XML.serialize = function(node) { inclua o seguinte: var XML = {};
    • O trecho vai ficar como na imagem abaixo:
    • Abra o Selenium IDE e corra para o abraço!


    Considerações com o Selenium RC

    Se tu fores portar o teu script do Selenium IDE para ser executado por linha de comando no Selenium RC tu vais previsar baixar a user-extension do Flow Control, isso porque pelos passos que eu coloquei aqui nós a instalamos via Addon do Firefox, e se tu tentar executar o teu script com somente as outras duas user-extensions (datadriven e includeCommand4IDE) ele não vai rodar por não conhecer o comando while.

    Baixe o .js do FlowControl no site abaixo e adicione ele no parametro de execução no RC.
    http://51elliot.blogspot.com/2008/02/selenium-ide-goto.html

    ATUALIZADO: para executar os scripts via linha de comando com o Seleium RC temos o seguinte problema: temos três arquivos .js que utilizamos no Seleniun IDE (flow control, includeCommnads e dataDriven) e no Selenium RC só podemos inserir um: o user-extension.js.
    Então como executar os scripts via linha de comando???

    A resposta é: copie o conteudo de cada arquivo .js e cole crie um arquivo user-extension.js e cole com o conteudo de cada um. Quando você for fazer isso é necessário colar os arquivos na ordem que o Selenium IDE usa cada comando, que deve ser o seguinte:
    • Copie o conteudo do arquivo FlowControl.js e cole no arquivo user-extension.js
    • Copie o conteudo do arquivo includeCommand4IDE e cole no arquivo user-extension.js
    • Copie o conteudo do arquivo DataDriven e cole no arquivo user-extension.js
    E qual a vantagem de executar os scripts Data Driven com o Selenium RC: executar em diferentes browsers! :D

    A linha de comando para a execução via Selenium RC seria essa:
    java -jar selenium-server.jar -userExtension user-extensions.js -htmlSuite *iexplore "http://eliasnogueira.info" "C:\pasta\suite.html" "C:\pasta\resultado.html"

    Atenção para alterar as seguinte as seguintes informações para o local do suite e resultados que tu necessita:
    • C:\pasta\suite.html
    • C:\pasta\resultado.html
    Não esqueça que você tem que estar no diretório do Selenium Server para executar a linha de comando!

    Abraço a todos vocês e bom divertimento!!!

    15 comentários:

    1. Valeu rapah, estava justamente precisando entender melhor essa entrada com massa de dados

      ResponderExcluir
    2. E como que eu adiciono 2 arquivos JS na minha linha de comando no Selenium RC? Eu terei que copiar o conteudo de um arquivo e colar no outro e usar apenas 1 arquivo user-extensions.js?

      ResponderExcluir
    3. Parabéns pelo excelente post!
      Estava mesmo precisando disso mas não tinha idéia se dava pra fazer.
      Vai melhor e muito minha vida :D

      Continue nos auxiliando e mostrando novos caminhos com os posts.

      ResponderExcluir
    4. Ótimo artigo!!
      Penei um pouco pra conseguir rodar o script... o link para o includeCommand4IDE está desatualizado no blog, baixei a versão 1_3 do artigo original e assim funcionou sem problemas ;)

      ResponderExcluir
    5. Oi Elias,
      tem como fazer um script no Selenium que "leia" um número gerado dinâmicamente por uma aplicação e o escreva em um txt ou em algum lugar onde eu possa recuperá-lo depois?

      Estou tentando gerar um massa de teste, mas preciso guardar os números dos documentos gerados e não sei como fazer isso usando selenium.
      Qualquer ajuda é bem-vinda :)

      ResponderExcluir
    6. Fazer com que o Selenium "leia" um código dentro da página é possível usando Expressão Regular, agora pra ele pegar estas informações e gravar num TXT é necessário ou criar uma user-extension que faça isso ou utilizar o Seleniun RC com alguma linguagem de programação.

      O que tu usa: IDE ou RC?

      Abraço!

      ResponderExcluir
    7. Oi Elane!
      Não entendí a tua primeira pergunta... O que exatamente tu quer guardar numa variável?

      Para a segunda pergunt o problema deve estar relacionado com a tua dúvida do includeCommand4IDE... Este arquivo deve ter a extensão .js
      Tenta colocar a extensão e ver se o script vai executar. Qualquer coisa posta aqui denovo :)

      ResponderExcluir
    8. Estou com um problema no Selenium RC.
      Aqui na empresa usávamos o Selenium IDE para automação e dentro dele usávamos um monte de extensões .js (string_random, rowsTable, randomRange, getTableRows, etc), extensões estas que criavam string randomicamente, escolhiam campos aleatoriamente e outras coisas e a gente usava isso para fazer (ou simular), meio que um data driven agora temos ou outro sistema para testar e precisamos fazer os testes em 4 navegadores e 3 versões de cada navegador por isso temos que migrar para o Selenium RC.
      Minha duvida é. É melhor usar estas extensões .js no arquivo user-extension.js ou criar uma arquitetura própria do Selenium RC (se é que existe isso) para a criação de arquivos aleatórios.

      E obrigado pelo post e pelo blog esta sempre ajudando a gente aqui em alguma coisa.

      ResponderExcluir
    9. Oi Emanuel!
      O ideal é criar uma arquitetura já na linguagem de programação que vocês irão utilizar, isso deixa voces mais flexiveis no desenvolvimento dos testes...

      Nessa transição tu ainda podes utilizar o arquivo user-extensions.js no codigo para utilizar as funções contidas nele. Via codigo tu deves criar um remote configuration (RemoteControlConfiguration) e adicionar a user-extension como arquivo (setUserExtensions)

      Qualquer duvida prende o grito :)

      ResponderExcluir
    10. Elias, primaeiramente obrigado pelo teu post! Fui muito util para iniciar com o data driven. Outra coisa quanto ao comando file://c:/testdata.xml no seu post está "file:///". Tenho também uma dúvida, só consegui carregar meu XML após retirar os acentos do mesmo, você sabe algo a esse respeito?

      ResponderExcluir
    11. Olá Tytta!
      Obrigado pelo teu feedback!
      O correto é utilizar três barras mesmo (file:///) mas isso o Selenium IDE corrige pra ti :)
      A questão do acento é por causa do encoding da extensão. O recomendado mesmo é utilizar o arquivo sem acentos e sem espaços no nome.

      ResponderExcluir
    12. Primeiramente gostaria de dar os parabéns pelo post! Me ajudou bastante aqui! :)

      Sobre o fato de não conseguir carregar o xml por conter acentos nos dados isso aconteceu comigo também.

      Para resolver isso, converti o arquivo XML pelo notepad++:
      Formatar>Converter para UTF-8 (sem BOM). Salvando o xml com esta codificação funcionou legal \o/

      Abs!

      ResponderExcluir
    13. Oi Elias, achei ótimo seu post, esclareceu minhas dúvidas... mas
      estou tendo um problema com o exemplo porque estou usando Ubuntu e o locator não está localizando meu arquivo 'dados.xml', tens alguma dica? Obrigada!

      ResponderExcluir
    14. Olá Elias,

      Estou começando a usar o selenium e me deparei com a seguinte situação:
      Se for necessária a utilização de 2 arquivos de dados xml, como tratar para o selenium Ide não se perder quando chegar ao final do arquivo. O que tenho é mais ou meno o seguinte

      CasoTeste1
      loadTestData file://C:/Selenium/Dados/Primeiroarquivo.xml
      open /XX/XX/XXXXXX
      command1
      while !testdata.EOF()
      nextTestData
      Command 1
      Command 2
      Command 3
      loadTestData file://C:/Selenium/Dados/Segundoarquivo.xml
      while !testdata.EOF()
      nextTestData
      Command 2
      Command 3
      Command 4
      endWhile
      Command 4
      Command 5
      endWhile

      Se puder me ajudar agradeço.

      ResponderExcluir