Mostrando postagens com marcador automacao. Mostrar todas as postagens
Mostrando postagens com marcador automacao. Mostrar todas as postagens

quarta-feira, 4 de setembro de 2013

O que é Headless Browser e porque você testador deve saber sobre

O que é Headless Browser

Do início, qualquer browser web tem que ser capaz de fazer três coisas:
  1. Dado um endereço, acessar uma página html
  2. Renderizar o conteúdo em DOM, executar scripts dentro da tag script, e torná-lo disponível na página
  3. Renderizar o DOM em um conteúdo visual
Um browser que somente faz o primeiro item é chamado de "text-based"
Um browser que cobre os três itens são os browsers que conhecemos atualment
Um headless browser cobre os dois primeiros itens

Logo, headless browser um browser web sem uma interface gráfica, ou seja, não conseguimos ver o conteúdo da página na nossa tela, mas este browser consegue executar qualquer ação sobre a URL desejada.


Para que ele serve?

Basicamente para duas coisas: como crawler e como um browser para testes mais rápidos.


Browser para testes mais rápidos?

A crescente utilização de headless browsers é a capacidade de executarmos testes de uma maneira muito mais rápida do que um browser com interface gráfica.
Ele se torna mais rápido por não necessitar carregar alguns conteúdos visuais, como aplicar estilos visuais em elementos e carregamento de imagens.

Eles podem ser utilizados para executar a sua suíte de automação por completo, mas o maior ganho em ter scripts de teste executando em um headless browser é velocidade com que temos um feedback.

Pense em um sistema de Integração Contínua, a cada comportamento (commit, tempo, versão, etc...) um sistema de CI faz todo um processo (compilação, testes unitários e/ou integração, deploy e testes de aceitação). Neste processo um dos últimos (se não o último) são os testes de aceitação (aquele que abre um browser web e executa todas as ações), mas executar estes testes diariamente em um ambiente de CI toma muito tempo para nos dar um feedback que necessitamos.

O que algumas pessoas costumam fazer é separar uma pequena parte dos scripts mais importantes (smoke ou sanity) com ferramentas conhecidas (Selenium, Watir, Robot Framework), mas estes ainda tomam um tempo precioso na execução por abrirem um browser real e executarem uma série de ações.

Outras pessoas, e isso vem se tornando popular, criam ou atualizam scripts para executarem sobre headless browser. Isso nos dá um enorme ganho de execução nestes testes mais importantes e um feedback mais rápido se algum comportamento que será visualizado pelo usuário não estiver ok.


Quais headless browsers podemos utilizar?

Há uma séria de headless browser disponíveis. A grande maioria delas (e as melhores) são inclusive open source. Uma grande parte dela é construida sobre o WebKit e é escrita (tanto o código do browser quanto o script para executar o teste) em JavaScript.
Abaixo vou listar apenas alguns, e mais populares:

Um ponto interessante é que o Selenium/WebDriver pode executar testes em dois dos mais populares headless browsers:


Onde posso ver um exemplo?

Aqui mesmo no SemBugs existe um post de uma apresentação minha no Web Test Meeting sobre como usar o básico do CasperJS.
O vídeo possui um pouco mais de 1h.

Apresentação sobre CasperJS no Test Web Meeting

Observação

Os possíveis termos que você testador pode não conhecer contém links para a sua descrição.
É totalmente recomendado que você leia também cada item com um link ;)

Abraços!

terça-feira, 9 de julho de 2013

Apresentação sobre CasperJS no Test Web Meeting

Oi pessoal!
Hoje tivemos a primeira reunião do Test Web Meeting, uma iniciativa do site/blog Qualidade de Software do Eduardo Freitas que visa reunir os nerds testers a falar sobre algum tema que foi votado antes da reunião através do Call4Paperz.

Hoje (09/07/2013) eu falei sobre CasperJS, uma excelente ferramenta de automação web headless browser. O foco nesta primeira apresentação foi mostrar, de forma bem básica, como começar a utilizar o CasperJS e uma pequena comparação com o Selenium em termos de tempo de execução, onde ele costuma ser quase 2x mais rápido do que o Selenium.

Abaixo está o vídeo da primeira reunião!
Não deixe de acessar o site Qualidade de Software, submeter uma apresentação e votar nas ativdas no Call4Paperz.




Links de ferramentas e conceitos comentados na apresentação:
Abraços!


segunda-feira, 25 de fevereiro de 2013

Como aprender sobre Selenium (de forma gratuita ou paga)

Olá pessoal!
Recebo quase todos os dias e-mails de profissionais da área perguntando como eles podem aprender sobre Selenium e onde podem encontrar materiais.

Este post se destina a isso: como aprender Selenium de uma forma "gratuita" ou não!
Quando eu falo Selenium, na verdade estou falando de WebDriver (apesar de existirem pessoas que querem aprender sobre o Selenium IDE e vou citar isso, o foco maior é em WebDriver)

Aprendendo Selenium de forma gratuita
Atualmente, até onde eu sei, não existe nenhum treinamento gratuito sobre Selenium.
O aprendizado gratuito pode se dar através de:
  • Leitura da documentação
  • Leitura e entendimento da API
  • Prática
  • Apresentações
  • Desafios Selenium

Leitura da documentação
Existem duas documentações padrão do Selenium:
  • Através do site http://seleniumhq.org: neste site você pode acessar a 'aba' Documentation e ler realmente a documentação. Há muita coisa boa lá e realmente te dá uma boa base inicial


O ideal é você ler todos os documentos contidos no Wiki, mas estes itens acima já irão lhe dar um overview sobre o WebDriver


Leitura e entendimento da API
Com o WebDriver é inevitável: temos que programar/desenvolver nossos testes utilizando alguma linguagem de programação!
Logo é um pré-requisito que você conheça, pelo menos, o básico da liguagem de programação de sua escolha e que também saiba como ler a API (documentação das ferramentas/plugins/frameoworks) implementados em uma determinada linguagem.

Podemos visualizar abaixo a lista das linguagens de programação formalmente suportadas com WebDriver e o link de cada API (documentação):

Prática!
Para aprendermos qualquer ferramenta não tem jeito: temos que praticar!
Logo a prática é um elemento fundamental do nosso aprendizado.
Você pode praticar em diversos sites web, mas aqui vai minha recomendação:
  • Começe a praticar em sites/aplicações simples
  • NUNCA tente praticar automatizando o login do Gmail, Yahoo! e outros...
  • Utilizar CMS ou lojas virtuais open source para praticar é uam boa. Você pode praticar num Joomla, Prestashop, por exemplo

Apresentações
Sempre é bom dar uma "Googleada" para encontrar apresentações ou links.
Eu recomendo dar uma olhada no SlideShare, site que contém uma gama de apresentações publicadas e diversas sobre Selenium.

Desafios Selenium
Foi uma iniciativa que eu criei em 2011 lançando um problema real, onde o mesmo deve ser automatizado com Selenium IDE.
Os desafios possuem a resolução explicada em vídeo, o que facilita o entendimento.
Por enquanto eu tenho somente 5 desafios e todos com respostas para o Selenium IDE, porém logo em breve voltarei a postar mais desafios em ambos os formatos: Selenium IDE e WebDriver!


Aprendendo Selenium de forma paga
Obviamente sempre temos alternativas pagas! Geralmente esta alternativa foca mais no que cada um precisa aprender e dependendo da forma que você escolher, um curso por exemplo, você conseguirá (ou não, pois depende de você) tirar um maior proveito e resolver problemas e dúvidas que você possa ter. O aprendizado pago pode ser:
  • Através de Cursos
  • Através de Livros

Atavés de Cursos
Existem dois treinamentos sobre WebDriver (um que cobre Selenium IDE que eu conheço), que serão listados abaixo:

Treinamento de Selenium (IDE, RC, WebDriver) do Elias Nogueira (eu)
Há algum tempo eu dou treinamento sobre Selenium.
Os treinamentos são no formato EAD síncrono, traduzindo, são treinamentos via videoconferência ao vivo. O aluno acessa um link onde vê a tela do instrutor e segue suas instruções.

Atualmente o curso é dividido em 4 módulos:
  • Selenium IDE Básico
  • Selenium IDE Avançado
  • WebDriver Básico
  • WebDriver Integrações
Todos os exercícios cobrem as principais dúvidas e interações que faremos na "vida real". Os exercicios resolvidos no Selenium IDE e WebDriver são disponibilizados, bem como uma apostila e certificado de participação.

Para saber mais sobre o treinamento acesse: http://sembugs.blogspot.com.br/p/curso-de-selenium.html


Treinamento de WebDriver (em inglês) do Alan Richardson (EvilTester)
Um cara chamado Alan Richardson, mais conhecido como EvilTester (seu blog) criou um treinamento sobre WebDriver no site Udemy.
O treinamento são video-aulas em inglês que mostram como trabalhar com o WebDriver em diversos pontos:
  • Navegação
  • Suporte dos testes com JUnit
  • Locators
  • Interações
  • RemoteWebdriver
  • CI

Link do treinamento: https://www.udemy.com/selenium-2-webdriver-basics-with-java/


Através de Livros

Existem livros muito bacanas sobre Selenium, mas infelizmente para alguns estes livros são em inglês (pra quem não consegue ler livros em inglês ainda fica o incentivo para aprender!)



Livro: Selenium Simplified

Este livro é do mesmo autor do curso do Udemy que eu coloquei acima: Alan Richardson. Este livro sobre a utilização do Selenium RC/WebDriver utilizando Java e JUnit.
É muito parecido com o próprio treinamento que o autor tem, mas os itens cobertos no livro possuem mais detalhes.

Link da página do livro: http://www.compendiumdev.co.uk/selenium/





Livro: Selenium Testing Tools Cookbook

Este livro mostra, além do básico de programação com WebDriver, problemas reais e como resolvê-los.
Também apresenta como fazer integrações de ferramentas de BDD e ATDD, como executar testes no Selenium Grid, como capturar evidências e como executar testes em browsers de dispositivos móveis (Android e iOS)

Link da página do livro: http://www.packtpub.com/recipes-to-master-selenium-2-testing-tools-cookbook/book



Livro: Selenium 2 Testing Tools

Este livro é de autoria de um dos commiters do Selenium: David Burns. Neste livro o autor aborda todos os conceitos  básicos do WebDriver unidos a alguns Design Patters para ajudar o leitor a desenvolver melhor usando o WebDriver.

Link da página do livro: http://www.packtpub.com/selenium-2-testing-tools-beginners-guide/book






Espero que este post seja de grande ajuda aqueles que desejam iniciar o aprendizado do Selenium.
Qualquer dúvida ou sugestões de links, cursos e livros deixem um comentário neste post :-)

Abraços!


terça-feira, 5 de fevereiro de 2013

TDD - Test Driven Development para Testadores


Olá pessoal!
No dia 02/02/2013 eu tive o prazer de falar sobre TDD - Teste Driven Development no Campus Party Brasil 2013.

Nesta palestra abordei um conteúdo mais prático, que pode ser visto nos slides e também um exemplo guiado que está disponível no GitHub:
https://github.com/eliasnogueira/tdd-exemplo

Mais abaixo vou escrever os pontos mais importantes da apresentação.
Fica a dica para você:
  1. Ler o post
  2. Ver a apresentação
  3. Ver o projeto no GitHub
  4. Tentar executar o projeto do GitHub em casa.

Mas porque o Elias, um tester, deu palestra sobre TDD (que é de dev)?
Cada vez mais, na minha visão, o testador se faz um profissional cada vez mas técnico e polivalente (palavra bonita), mas que em poucas palavras quer dizer que o tester não precisa programar todo o dia usando TDD, mas precisa saber o que é como como utilizar essa técnica.



TDD - Test Driven Development from Elias Nogueira







 Se software fossem carros... como poderíamos garantir que tudo funciona? Se pensarmos um pouco no processo de criação de um carro temos uma infinidade de peças que devem, além de ser criadas por si só, devem funcionar com outras peças, resultado ao final um carro totalmente utilizável.

Pense que você precisa "testar um carro"... e guarde esse pensamento com você por enquanto.





 Mas quem testa? O desenvolvedor? Pelo que conhecemos de Teste de Software não!

No modelo que conhecemos o testador que executa esta atividade certo? Ele deve garantir que o sistema funciona depois que um ou mais funcionalidades foram desenvolvidas.





No modelo tradicional de desenvolvimento de software (cascata, e sim, eu apresentei um modelo cascata ao invés do RUP porque grande parte ainda desenvolve assim) temos as conhecidas fases do desenvolvimento, mas teste é a penúltima fase. Logo testar torna-se um processo que, além de oneroso, é muito caro!

Logo como garantir uma melhor entrega para testes com uma maior qualidade?






Uma técnica conhecida (deveria ser bem mais conhecida) e muito negligenciada por diversos fatores é o TDD - Test Driven Development, ou Desenvolvimento Orientado a Teste.

Com ele o próprio desenvolvedor (e seria muito legal se adicionássemos: "com a ajuda do testador") cria testes de um jeito diferente de programar e garantir que o que ele está desenvolvendo terá uma melhor qualidade.





Agora é interessante dar uma olhada na sequencia de slides que explica como desenvolver um código para converter os símbolos do número romano em símbolos.

Depois vale muito a pena olhar o projeto no GitHub e tentar segui-lo em sua máquina local: https://github.com/eliasnogueira/tdd-exemplo





O processo de desenvolvimento de uma funcionalidade ou aplicativo utilizando TDD é bem simples: primeiro criamos um teste que não passa, depois testamos refatorá-lo para que ele passe sempre, obviamente, penando na melhor e mais simples implementação naquele momento.

Se você notar todos os passos do projeto descrito no GitHub são guiados através de TDD.





E, obviamente, existem muitos benefícios em adotar esta técnica, onde um dos maiores benefícios são a simplicidade, feedback rápido e segurança.

Conseguimos ter uma bateria de testes de unidade criados sem grande esforço e já cobrindo boa parte da funcionalidade.

Assim o novo código criado já nasce testado!






Utilizando TDD conseguimos facilmente mostrar o ganho em tempo, onde desde o inicio o código sai testado e pronto para ser alterado (refatorado) ou usado por outro método/classe.

Se compararmos com o modelo tradicional, teríamos apenas testes no final do desenvolvimento de todo o código.





E, apenas para alinhar, TDD não é teste! TDD é uma técnica de design de código que ajuda, e muito o testa da aplicação/funcionalidade.

Embora o termo "teste" seja utilizado ao usar TDD estamos dando muito mais atenção ao design da classe/funcionalidade do que realmente teste.



A palestra possui vários insights e o exemplo dos números romanos retirados do livro "TDD - Teste Driven Development: Teste e Design no Mundo Real" do autor Maurício Aniche, editora Casa do Código
http://www.casadocodigo.com.br/products/livro-tdd 

Abraços!





quinta-feira, 3 de maio de 2012

Como obter conhecimento técnico em Teste de Software (de forma gratuita)

Olá pessoal!
O intuito deste post é mostrar diversas fontes de conhecimento na internet para aqueles testadores que querem se tornar mais técnicos e não sabem por onde começar.
Nem sempre é preciso correr para cursos pagos (que também é uma boa pedida).

Aqui vou listar diversos links sobre ferramentas, tecnologias e metodologias para estudo.
Um único pont bom (ou ruim para alguns) é que a maioria do material é em inglês (nada que um google translator não resolva se você não souber inglês)

Ponto importante: este post será um post "vivo". Portanto a sugestões de todos vocês sobre cursos e conteudos gratuitos de boa qualidade será ótimo para contribuir com a disseminação de conhecimento.


Diversos

W3Schools
Possui diversos tutoriais para tecnologia web gratuitos.

Fundação Bradesco
A Fundação Bradesco possui diversos cursos de informática, muito deles que podemos aproveitar para o nosos aprendizado.
Tente focar nos cursos dos itens Banco de Dados e Desenvolvimento de Aplicativos. Dento deste último eu não recomendo os seguintes cursos por não ser o foco deste aprendizado: Expression Blend, Ilustração & Design Gráfico para Web e Silverlight.

Qualifico Ensino e Tecnologia
Não estou fazendo propaganda deles, mas eles possuem um mini curso gratuito de Teste Exploratório que vale a pena ser assistido.

SQL Básico

Xpath

Ferramentas de Automação
Lista de ferramentas open source para automação de teste. Leia-se open source por ferramentas de código e conteudo (documentação) aberto.

Selenium

AutoIT

Lógica de Programação

Não fazendo propaganda, mas aqui você encontra muitos cursos básicos por um baixo custo


Linguagem de Programação

Java

Ruby

Colaboradores deste post

Leonardo Galani: do blog keeptesting.com.br sobre xpath
Fernanda Lessa: mandou sua colaboração através da lista guts-rs@googlegroups.com sobre a Fundação Bradesco

segunda-feira, 30 de abril de 2012

Como aprender a programar para teste de software (automação)?

Na lista de emails do DFTestes tivemos uma pergunta, que no meu ponto de vista foi muito bem colocada, que era:
Como vocês aprenderam a programar especificamente para testes?

Eu, particularmente, fui programador comercial no início da minha carreira em TI, porém não há uma diferenciação entre programar para "testes" e programar comercialmente.

Não deixe de ler depois o post Como obter conhecimento técnico em Teste de Software (de forma gratuita)
Em testes, basicamente, precisamos aprender o básico dos dois itens abaixo:
  • Aprender o básico de alguma linguagem de programação
  • Aprender sobre a ferramenta de automação de teste funcional escolhida

Como aprender o básico de alguma linguagem de programação?
Eu sempre falo que para ser um automatizados o profissional de testes não precisa ter grandes skills de desenvolvimento, apenas saber, entender e aplicar o básico de uma linguagem de programação.

Mas Elias, o que é o básico de uma linguagem de programação?
Para ser mais assertivo com essa resposta fiz uma pesquisa nos principais cursos de desenvolvimentos das principais empresas de treinamento do Brasil. Foquei nas linguagens Java, .NET e Ruby por serem as comercialmente mais usadas. Eis o resultado:
  • Sintaxe básica de linguagem
    • Fundamentos da linguagem
    • Variáveis (tipos, escopo)
    • Operadores (aritméticos, comparação e lógicos)
    • Fluxo de controles (if/else, switch, while, do/while, for)
    • Arrays (bidimensionais, multidimensionais)
  • Orientação a Objetos
    • Classes
    • Encapsulamento
    • Associação
    • Herança
    • Polimorfismo

Os itens acima são muito básicos em qualquer linguagem, e especificamente para o item 2 - Orientação a Objetos para as linguagens orientadas a objetos (todas as tres citadas).

Quem fez ou está fazendo faculdade olhe com carinho a lista acima e responda: Há algum destes itens que você não viu na faculdade?

Geralmente todos estes pontos são abordados por qualquer disciplina de programação na faculdade e não nos damos conta da importância dos mesmos :-)

Como aprender sobre uma ferramenta de automação de teste funcional?
Ai vem o segundo ponto. Posso dizer que uma ferramenta tem dois segmntos:

Em uma aplicação estilo IDE a ferramenta é um software capaz de gravar os passos que executamos sobre o sistema. Após podemos editar o código-fonte gerado para melhorar o teste. Este código-fonte pode ser apresentado em diversas linguagens diferentes, porém geralmente uma única é utilizada pela ferramenta. A ferramenta também dispôe de funcionalidades prontas para o uso no script de teste, como checkpoints/asserções automáticas, conexão com banco de dados, etc...
Para o aprendizado desta ferramenta há três caminhos:
  • Leitura da documentação básica da ferramenta (telas, como gravar e executar testes, etc...)
  • Entendimento das principais funcionalidades "prontas" da ferramenta
  • Aprendizado da linguagem de programação adotada pela ferramenta

Exemplos deste tipo de aplicação são: TestComplete, HP QuickTest Professional, IBM Functional Tester entre outras.

Exemplo de uma aplicação estilo IDE - TestComplete
 
Em uma aplicação estilo API um ou vários arquivos (geralmente chamados de bibliotecas) são disponibilizados para que o profissional utilize métodos daquela API, ou seja, um conjunto de métodos/funções para teste são utilizados para que possamos escrever um script de teste.
Neste modelo os profissionais importam esses arquivos (bibliotecas) para uma IDE de Desenvolvimento (diferente da aplicação estilo IDE que mencionei acima) como Eclipse, Visual Studio, Netbeans entre outras.
Durante a programação do script de teste o profissional vai escrevendo os testes, condições e quaisquer tipos de funções que não estejam presentes, como o acesso ao banco de dados.
Para o aprendizado desta ferramenta há três caminhos:
  • Leitura da documentação básica da ferramenta
  • Leitura de sua API
  • Exercitar as funções da API na utilização da ferramenta

Exemplos deste tipo de aplicação são: Selenium, Watir, Robot Framework entre outras.

Estilo de uma aplicação estilo API usando Eclipse IDE - Selenium

Aplicações estilo API exigem uma capacidade/conhecimento de programação maior do que as aplicações estilo IDE

Adendo
É claro que atualmente existem vagas que não exigem somente o básico de programação para trabalhar na área de teste, como as vagas de SDET - Software Developer in Teste que são posições de desenvolvedores que também trabalham em testes com o intuito de criar sistemas (frameworks) para testar aplicações, além de também conhecer desenvolvimento muito bem.
Vamos encontrar este tipo de vaga em grandes empresas como Google, Microsoft, Amazon, Facebook entre outras.
Infelizmente isso não é uma realidade no Brasil, mas isso dá outro post depois...

Dica
Pela internet é faci encontrar diversos materiais sobre como aprender determinada linguagem de programação. Eu recomendo ler os links abaixo para quem quer começar a estudar por conta com um material confiável:

Abraços!

segunda-feira, 16 de abril de 2012

Criptografar senhas em um script automatizado é realmente necessário?

Hoje tive uma conversa com um aluno do curso de Selenium que me fez pensar um pouco...
A pergunta era como criptografar a senha gravada pelo Selenium durante a gravação dos testes e execução do mesmo.

E eu me perguntei: pra que? rs

A pergunta é pertinente, pois há uma preocupação com a segurança dos dados dentro do script.
Vamos a alguns pontos...

Que ganho teriamos em "criptografar" a senha de dentro de um script de teste?
Obviamente o ganho seria em segurança.
Qualquer pessoal má intencionada poderia utilizar aquele usuário e senha para acessar o sistema, principalmente em produção e utilizá-lo de forma indevida. Até mesmo passar o usuário e senha para uam pessoa acessar um sistema em produção para utilização própria (leia-se para não pagar/comprar), e muitas outras ações que podem ser feitas.


Como a grande maioria dos profissionais trabalha com esta questão em automação
Na grande maioria das vezes a codificação de uma senha dentro do script não é levada em consideração porque:
  • Os servidores de testes são conhecidos e possuem acesso apenas aos colaboradores da empresa
  • Usuários específicos são criados (ou deveriam) para diversos testes
  • Mesmo em ambiente produtivo (servidor de produção) o acesso é controlado através de usuários apenas para testes especificos, onde estes usuários são desativados no sistema em produção e, obviamente, possuem uma senha mais "segura"
Pense no trabalho que dará você codificar uma senha e, no momento da execução do script, ter que decodificar a mesma para que a aplicação execute. No mínimo um desenvolvimento usando reflexão terá de ser criado. E como diria na minha terra "é muita mão de obra" (dá muito trabalho) fazer isso.

Uma possivel solução rápida se simples
A solução não exclui o fato de segurança de acesso, etc... Porém pode tornar as coisas mais simples e tranquilas e na verdade vai te ajudar a criar "melhor" os testes scripts: colocar este dado em um arquivo externo!

Obviamente tu continua tendo um acesso a senha daquela, mas não diretemente no arquivo

O que deveríamos fazer então?
O ideal, na minha visão, é:
  • Criar usuários especificamente para rodar os scripts automatizados
  • Sempre possuir um processo/automação para desativar os usuários quando não estiverem em uso, principalmente em ambiente produtivo
Bom, estas são as minhas pequenas considerações em relação a este tema.
E como vocês costumam fazer?
Essa mesma idéia de "criptografar" os dados já passou na cabela de vocês?

Abraços!

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!!!

    terça-feira, 19 de outubro de 2010

    Projeto de Integracao Selenium x Mantis x Testlink

    Olá Pessoal!
    Como último post sobre a Integração com o Selenium e ferramentas de Gestão de Teste e Gestão de Defeitos criei um projeto em Java que integra o Selenium, Mantis e Testlink.

    É recomendado você ler os dois post's abaixo:

    Se você já leu estes dois tutoriais, continue lendo este post...
    Este projeto de exemplo vai:
    • Executar um script de teste no Selenium RC
      • O script de teste irá falhar
    • Reportar um bug no Mantis anexando uma imagem do browser no momento do erro
    • Reportar o resultado do teste (que será com falha) ao Testlink
    • Associar o bug aberto ao Caso de Teste no Testlink
    Abaixo será apresentado somente as modificações executadas para a criação de um exemplo único. Se você precisar de mais explicações sobre algum item da integração, por favor, consulte os post's anteriores.

    1. Organização
    Este projeto foi dividido nos seguintes pacotes, conforme descrito abaixo:
    •  com.blogspot.sembugs.mantis
      • ConnectMantis.java: Classe que faz a conexão com o Mantis
      • MantisReport.java: Classe que reporta o bug no Mantis
    • com.blogspot.sembugs.test
      • CasoTeste.java: Caso de Teste de exemplo
    • com.blogspot.sembugs.testlink
      • ResultadoExecucao.java: Classe que reporta o resultado da execução do teste
    • com.blogspot.sembugs.util
      • IConstantes.java: Interface com dados comuns as classes

    2. Modificações
    A seguir serão apresentados os trechos das classes que foram alterados e os devidos comentários sobre as alterações

    MantisReport.java
    Nesta classe foram feitas as seguintes alterações:
    • Linha 1: Mudança do método, que agora tem como retorno um String.
    • Linha 8: Criado um atributo local do tipo long para retornar o ID do bug cadastrado
    • Linha 12: O atributo local é transformado em uma String e atribuido a variável bugID
    • Linha 22: Adicionado o retorno do método

    PS: A classe abaixo está omitindo uma série de linhas de código, sendo apresentado apenas as mais relevantes perante as alterações.

    1:  public static String reporIssue(String sumario, String descricao, String categoria, String informacaoAdicional, String evidencia, String nomeArquivo) {  
    2:          IMCSession sessao = null;  
    3:          String arquivo = nomeArquivo + ".png";  
    4:          String bugID = null;  
    5:            
    6:          try {  
    7:        // submete o bug no Mantis  
    8:        long id = sessao.addIssue(issue);     
    9:        sessao.addIssueAttachment(id, arquivo, "image/png", Base64.decodeBase64(evidencia));  
    10:          
    11:        // retorna o ID do bug como String, para fazer o relacionanmento do bug com o Testlink  
    12:        bugID = String.valueOf(id);  
    13:          
    14:          } catch (MalformedURLException e) {  
    15:              System.err.println("Erro na URL de acesso ao Mantis");  
    16:              e.printStackTrace();  
    17:          } catch (MCException e) {  
    18:              System.err.println("Erro na comunicacao com o Mantis");  
    19:              e.printStackTrace();  
    20:          }  
    21:            
    22:      return bugID;  
    23:      }  
    24:  }  
    


    ResultadoExecucao.java
    Nesta classe foram feitas as seguintes alterações:
    • Linha 1: Foi adicionado um novo parâmetro para a utilização do método: Integer bugID. É esperado que seja passado o ID do bug cadastrado para fazer a associação com o Testlink, mas não é obrigatório
    • Linha 5: Um verificação é feita para ver se o ID do bug será passado. Se sim há uma séria de atributos que são obtidos para que o resultado de execução do caso de teste contenha o bug associado. Isso foi adicionado porque o método da API do Testlink tem uma assinatura (parâmetros) diferente do do método que não associa o bug
    • Linhas 7, 8, 9 e 10: Todos os atributos locais necessários para a associação do bug no resultado do caso de teste.
    • Linha 12: Envio dos dados de resultado do teste ao Testlink utilizando o ID do bug para associação.
    • Linhas 13 e 14: Se o bug não for passado (for null) o envio do resultado de execução para o Testlink utiliza outro método para esta tarefa.

    1:  public static void reportTestCaseResult(String projetoTeste, String planoTeste, String casoTeste, String nomeBuild, String nota, String resultado, Integer bugID) throws TestLinkAPIException {  
    2:        
    3:    TestLinkAPIClient testlinkAPIClient = new TestLinkAPIClient(DEVKEY, URL);  
    4:        
    5:    if (bugID != null) {  
    6:            
    7:      Integer projectID = TestLinkAPIHelper.getProjectID(testlinkAPIClient, PROJETO_TESTLINK);  
    8:      Integer testPlanID = TestLinkAPIHelper.getPlanID(testlinkAPIClient, projectID, PLANO);  
    9:      Integer testCaseID = TestLinkAPIHelper.getTestCaseID(testlinkAPIClient, projectID, CASO_TESTE1);  
    10:     Integer buildID = TestLinkAPIHelper.getBuildID(testlinkAPIClient, testPlanID, nomeBuild);  
    11:    
    12:     testlinkAPIClient.reportTestCaseResult(testPlanID, testCaseID, buildID, bugID, false, nota, resultado);          
    13:    } else {  
    14:        testlinkAPIClient.reportTestCaseResult(projetoTeste, planoTeste, casoTeste, nomeBuild, nota, resultado);  
    15:    }  
    16:  }  
    


    CasoTeste.java
    Esta classe é a mesma utilizado nos outros dois tutoriais, porém com nome diferente.
    Basicamente foi alterado apenas o bloco finnally do script.
    • Linha 3: Foi adicionado o método para o report do bug, atribuindo para uma variável o ID do bug que foi adicionado.
    • Linha 5: Adicionado o novo método com o parâmetro do bugID, para que o bug seja associado ao resultado de execução do caso de teste.

    PS: A classe abaixo está omitindo uma série de linhas de código, sendo apresentado apenas as mais relevantes perante as alterações.

    1:  } finally {  
    2:    if (erro) {  
    3:      String bugID = MantisReport.reporIssue("Erro no Caso de Teste de Pesquisa de Livros", "Erro em alguma validacao ou validacao", "Automacao", msgErro, evidenciaErro, "CasoTesteMantisNOK");  
    4:                    
    5:      ResultadoExecucao.reportTestCaseResult(PROJETO_TESTLINK, PLANO, CASO_TESTE1, BUILD, msgErro, resultado, Integer.parseInt(bugID));      
    6:            
    7:      CasoTeste.fail(msgErro);  
    8:    }  
    9:  }  
    


    3. Baixando o código-fonte
    O projeto completo e funcional pode ser baixado no link abaixo (18 MB):

    http://www.eliasnogueira.com/arquivos_blog/selenium/integracao/mantis_testlink/selenium-integration.zip


    4. Verificando online o resultado de execução
    Se você baixar o projeto e já executá-lo ( ) poderá ver que os resultados no Testlink e Mantis serão colocados em ambas aplicações que tenho online.

    Para acessar ambos, utilize os seguintes dados de login:
    • Usuário: convidado
    • Senha: convidado
    Dentro do Mantis, que está acessível pela URL abaixo, você verá que o bug será reportado contendo os dados que passamos para o método utilizado na classe CasoTeste.java. Atente-se para o ID do bug e o horário de criação:

    http://www.eliasnogueira.com/arquivos_blog/mantisbt-1.2.3/


    Agora no Testlink, que está acessível pela URL abaixo, veremos que o resultado reportado foi com falha, está dentro do mesmo horário de criação do bug e tem o bug associado, conforme figura.



    Bom pessoal, por enquanto é isso! Abraço a todos!

    sexta-feira, 15 de outubro de 2010

    Integração Selenium e Mantis

    For foreing raders, please clique here to read this post in english (google translator)

    Não deixe de ler também a Integração do Selenium e Testlink.

    Escopo
    Este tutorial vai apresentar como efetuar a integração entre o Selenium RC e o Mantis, para que seja possível reportar automaticamente um bug quando um erro em um script do Selenium falhar.

    Criaremos um projeto em Java com o suporte do JUnit para a criação do script de teste com o Selenium. abaixo há uma lista de itens necessários para esse tutorial.

    O que é necessário?

    2. Preparando seu ambiente de Desenvolvimento
    A preparação do ambiente vai apresentar somente as bibliotecas necessárias para fazer a integração funcionar. Não é intuito deste item ensinar alguma coisa sobre o Eclipse ou sobre Java.

    2.1 Selecionando as bibliotecas necessárias
    Para rodar o script de teste com a integração e necessário os seguintes arquivos (bibliotecas e libraries) das seguintes API's / frameworks:
    • mantisconnect: necessário adicionar as seguintes bibliotecas
      • mantisconnect-client-api-1.1.1.0.jar
      • todas as libs, exeto a junit, da pasta lib
    • Selenium RC: necessário adicionar as seguintes bibliotecas
      • selenium-server.jar
      • selenium-java-client-driver.jar
    • JUnit: necessário adicionar o JUnit 4 que já vem com o Eclipse (Add Libraries)
    Abaixo segue a imagem das bibliotecas que foram adicionadas ao Eclipse.


     Para adicionar cada biblioteca você precisa clicar com o botão direito no nome do projeto e selecionar Build Path/Configure Build Path...



    Adicone também a biblioteca do JUnit, indo ao mesmo local (Configure Build Path...) e clicando no botão Add Library. Selecione JUnit e, em seguida, JUnit 4.

     2.1 Desenvolvendo o código-fonte
    A aplicação de exemplo, que está no final do post traz o código-fonte do script de teste e mais dois arquivos de código-fonte, que serão explicados abaixo.

    A primeira coisa a fazer é entender o script de teste primeiro. O package, os imports e comentários em javadoc foram excluídos para exemplificar o funcionamento da classe.
    Existem duas classes de teste, uma com execução OK e outra que forçará o erro para que seja possível o report automático do bug.
    Abaixo será apresentado o script que força o erro.

    1:  public class CasoTesteMantisNOK extends TestCase implements IConstantes {  
    2:      
    3:    Selenium selenium;  
    4:    SeleniumServer server;  
    5:      
    6:    String serverHost = "localhost";  
    7:    int serverPort = 4444;  
    8:    String browserStartCommand = "*firefox";  
    9:    String browserURL = "http://www.lojaexemplodelivros.com.br/";  
    10:      
    11:    boolean erro;  
    12:    String msgErro;  
    13:    String evidenciaErro;  
    14:      
    15:    public void setUp() throws Exception {  
    16:      selenium = new DefaultSelenium(serverHost, serverPort, browserStartCommand, browserURL);  
    17:      server = new SeleniumServer();  
    18:        
    19:      server.start();  
    20:      selenium.start();  
    21:    }  
    22:      
    23:    @Test  
    24:    public void testPesquisaLivro() throws Exception {  
    25:        
    26:      try {  
    27:        selenium.open("/");  
    28:        selenium.click("//ul[@id='nav']/li[1]/ul/li[2]/ul/li[1]/a/span");  
    29:        selenium.waitForPageToLoad("30000");  
    30:          
    31:        assertEquals("3 Item(s)", selenium.getText("//div[@id='main']/table[1]/tbody/tr/td[1]/strong"));  
    32:        assertEquals("[PRODUTO] - Use a Cabeça! Java", selenium.getText("link=[PRODUTO DE EXEMPLO] - Use a Cabeça! Java"));  
    33:        assertEquals("[PRODUTO DE EXEMPLO] - Entendendo e Dominando o Java: para Internet", selenium.getText("link=[PRODUTO DE EXEMPLO] - Entendendo e Dominando o Java: para Internet"));  
    34:        assertEquals("[PRODUTO DE EXEMPLO] - Ajax com Java", selenium.getText("link=[PRODUTO DE EXEMPLO] - Ajax com Java"));  
    35:          
    36:        selenium.click("//img[@alt='[PRODUTO DE EXEMPLO] - Ajax com Java']");  
    37:        selenium.waitForPageToLoad("30000");  
    38:        assertTrue(selenium.isTextPresent("2x R$ 222,25 sem juros"));  
    39:        assertTrue(selenium.isTextPresent("3x R$ 148,17 sem juros"));  
    40:        assertTrue(selenium.isTextPresent("4x R$ 111,13 sem juros"));  
    41:        assertTrue(selenium.isTextPresent("5x R$ 88,90 sem juros"));  
    42:        
    43:      } catch (AssertionError e) {  
    44:        reportError(e);  
    45:          
    46:      } catch (Exception e) {  
    47:        reportError(e);  
    48:          
    49:      } finally {  
    50:        if (erro) {  
    51:          MantisReport.reporIssue("Erro no Caso de Teste de Pesquisa de Livros", "Erro em alguma validacao ou validacao", "General", msgErro, evidenciaErro, "CasoTesteMantisNOK");  
    52:          CasoTesteMantisNOK.fail(msgErro);  
    53:        }  
    54:      }  
    55:    }  
    56:      
    57:    private void reportError(Throwable e) {      
    58:      erro = true;  
    59:      msgErro = e.getMessage();  
    60:      e.printStackTrace();  
    61:      evidenciaErro = selenium.captureEntirePageScreenshotToString("background=#FFFFFF");  
    62:    }  
    63:      
    64:    public void tearDown() throws Exception {  
    65:      selenium.stop();  
    66:      server.stop();  
    67:    }  
    68:  }  
    


    Basicamente há a criação dos atributos do Selenium e SeleniumServer para a execução, os métodos setup() e tearDown() do JUnit e o caso de teste automatizado.
    Note que o bloco do caso de teste (método testPesquisaLivro) está com um try-catch. Isso é necessário para que possamos reportar um bug quando o script falhar.

    Nas linhas 11, 12 e 13 foram criados atributos que controlarão os dados para o erro, e serão descritos logo mais.

    A linha 32 deste script irá falhar, propositalmente, para que o bug seja reportado. O trecho de código correto (que não causará um bug) é o abaixo e também esta no arquivo CasoTesteMantisOK:

    assertEquals("[PRODUTO DE EXEMPLO] - Use a Cabeça! Java", selenium.getText("link=[PRODUTO DE EXEMPLO] - Use a Cabeça! Java"));

    Existem 2 blocos com catch (um iniciando na linha 43 e outro na linha 46). Foram colocados dois somente para distinguir o tipo do erro, se um erro na validação (AssertionError) ou qualquer erro (Exception). Dentro destes blocos há um método chamado reportError passando como parâmetro a exception.
    Este método (linhas 57 a 62) informa através da variável erro que um erro ocorreu (passando true). Pega a mensagem de erro e coloca no atributo msgErro, faz com que a exception seja apresentada o console (e.printStackTrace()) e captura a imagem da página utilizando a função captureEntirePageScreenshotToString() para passar a imagem em formato de String Base64.

    PS: esse comando só funcionará rodando com a angine do Mozilla (Firefox) e no Google Chrome. Caso queira que o mesmo comando funcione no IE leia este post (em inglês).

    Na linha 50 e feito uma condição para ver se ocorreu algum erro (se o atributo erro está como true), caso positivo a função de report do bug é chamada.

    A linha 51 apresenta a função utilizada para reportar o bug, que será explicado logo mais. Neste momento você só precisa saber que é necessário informar os seguintes dados (nesta ordem) para o método:
    • Sumário do bug
    • Descrição do bug
    • Categoria do bug
    • Informação adicional do bug
    • Evidencia (como String Base64)
    • Nome do arquivo (que será anexado)
    A linha 52 força uma falha no script mostrando a mensagem de erro ocorrida.

    Classe MatisReport
    Dentro do projeto no pacote com.blogspot.sembugs há a classe MantisReport, que é a responsável por reportar o bug no Mantis. Eu gerei essa classe como chamada de uma função da API mantisconnect.

    PS: package, imports e comentários em javadoc foram excluídos para exemplificar o funcionamento da classe.

    1:  public class MantisReport implements IConstantes {  
    2:    
    3:      public static void reporIssue(String sumario, String descricao, String categoria, String informacaoAdicional, String evidencia, String nomeArquivo) {  
    4:          IMCSession sessao = null;  
    5:          String arquivo = nomeArquivo + ".png";  
    6:            
    7:          try {  
    8:              sessao = ConnectMantis.getSessao();  
    9:              IProject projeto = sessao.getProject(PROJETO);  
    10:                
    11:        Issue issue = new Issue();  
    12:          
    13:        issue.setProject(new MCAttribute(projeto.getId(), projeto.getName()));  
    14:        issue.setAdditionalInformation(null);  
    15:        issue.setOs(System.getProperty("os.name"));  
    16:        issue.setOsBuild(System.getProperty("os.version"));  
    17:        issue.setPlatform(System.getProperty("os.arch"));  
    18:        issue.setSeverity(new MCAttribute(70, "crash"));  
    19:        issue.setReproducibility(new MCAttribute(10, "always"));  
    20:        issue.setSummary(sumario + new Date());  
    21:        issue.setDescription(descricao);  
    22:        issue.setCategory(categoria);  
    23:        issue.setPriority(new MCAttribute(40, "high"));  
    24:        issue.setAdditionalInformation(informacaoAdicional);  
    25:          
    26:        long id = sessao.addIssue(issue);     
    27:        sessao.addIssueAttachment(id, arquivo, "image/png", Base64.decodeBase64(evidencia));  
    28:                
    29:          } catch (MalformedURLException e) {  
    30:              System.err.println("Erro na URL de acesso ao Mantis");  
    31:              e.printStackTrace();  
    32:          } catch (MCException e) {  
    33:              System.err.println("Erro na comunicacao com o Mantis");  
    34:              e.printStackTrace();  
    35:          }  
    36:      }  
    37:  }  
    

    A linha 5 cria um atributo que pega o nome do arquivo, que foi passado como parâmetro, e concatena a extensão ".png", que será necessário para anexar o arquivo no Mantis.

    Na linha 8 é feita uma chamada para o Singleton (que será explicado depois) para fazer a conexão com o Mantis e retornar um objeto de sessão do Mantis (IMSession)

    A linha 9 traz o projeto, que está na interface IConstantes, como objeto de projeto do Mantis (IProject). Isso é necessário para sabermos em qual projeto reportar o bug.

    Na linha 11 é criado uma issue (bug). A classe Issue representa um relato de bug.
    A linha 13 seta o projeto que reportaremos o bug e das linhas 14 a 24 passamos diversas informações do bug para o Mantis. Existe uma série de informações que podemos passar, eu coloquei apenas as mais relevantes aqui.

    Atenção: na linha 20 eu concatenei o sumário com a data atual (issue.setSummary(sumario + new Date());). Fiz isso para que seja possível executar diversas vezes o script sem duplicar o nome do bug no Mantis.

    Note que nas linhas 18, 19 e 23 é preciso criar um objeto MCAttibute para que seja possível passar informações de qualquer atributo no report do bug como Severidade, Prioridade e Frequencia.
    Serão sempre duas informações: o código e o nome do atributo.
    Você pode consultar o código e nome dos atributos no arquivo config_defaults_inc.php e consultar cada atributo.
    Se você quiser visualizar ou alterar estes atributos que estão no código-fonte, dê uma olhada nos atributos abaixo que estão contidos no arquivo citado acima:

    1:  $g_severity_enum_string    = '10:feature,20:trivial,30:text,40:tweak,50:minor,60:major,70:crash,80:block';  
    2:    
    3:  $g_priority_enum_string    = '10:none,20:low,30:normal,40:high,50:urgent,60:immediate';  
    4:    
    5:  $g_reproducibility_enum_string = '10:always,30:sometimes,50:random,70:have not tried,90:unable to duplicate,100:N/A';  
    

    Na linha 26 o bug é submetido para o cadastro, retornando o código do bug.

    A linha 27 adiciona um anexo no bug, que é a tela capturada pelo Selenium no momento do erro. Para isso é necessário passar para a função addIssueAttachment da sessão (e não da issue) os parâmetros: id do bug, nome do arquivo, tipo do arquivo e o array de bytes do arquivo (por isso a transformação em Base64, que é como o Selenium retorna a imagem).

    Essa classe foi criada para facilitar o report do bug, nada impede de criarmos outras funções com mais informações ou simplesmente colocar esse código todo no script. Isso foi feito pensando em uma maior reutilização de código... ;)

    Classe ConnectMantis (Singleton)
    Para que seja possível reportar o bug é necessário efetuar a conexão com o Mantis. A classe criada utiliza o Design Pattern Singleton, para que não exista várias instâncias de conexão com o Mantis, mantendo apenas uma ativa em toda a execução da aplicação.
    Não é o foco explicar como funciona o Design Pattern Singleton, mas você pode clicar nos links abaixo para aprender um pouco. Vou me ater apenas a um trecho do código desta classe.

    Design Pattern: http://en.wikipedia.org/wiki/Design_pattern
    Singleton: http://en.wikipedia.org/wiki/Singleton_pattern

    1:  public ConnectMantis() throws MalformedURLException, MCException {  
    2:    URL url = new URL(MANTIS_URL);  
    3:    sessao = new MCSession(url, MANTIS_USER, MANTIS_PWD);  
    4:  }  
    

    Na função acima, que está contida na classe é criado um objeto URL com a URL do Mantis que está na Interface IConstantes e na linha 3 é criado um novo objeto do tipo sessão (IMSession) passando a URL, usuário e senha do Mantis.

    Interface IConstantes
    A interface contém apenas constantes utilizadas em comum pela aplicação, e também para ter um ponto único de alterações de usuário e senha quando existir.

    1:  public interface IConstantes {  
    2:    static final String MANTIS_URL = "http://localhost/mantisbt-1.2.3/api/soap/mantisconnect.php";  
    3:    static final String MANTIS_USER = "administrator";  
    4:    static final String MANTIS_PWD = "root";  
    5:    static final String PROJETO = "Integracao";  
    6:  }  
    

    Na linha 2 a contante é a URL de acesso aos serviços SOAP do Mantis. Tome cuidado quando você for alterar essa constante, pois você terá que colocar o seu servidor (onde aqui está como localhost) e o nome de acesso a aplicação (aqui está como mantisbt-1.2.3)
    As outras contantes são o usuário na linha 3, a senha na linha 4 e o nome do projeto na linha 5.

    4. Execução e modificação deste tutorial
    Chegamos ao fim do tutorial. Se você deseja executar este tutorial baixe os fontes de exemplo criados no Eclipse e altere os dados de URL para o Mantis.

    Se você alterar os dados da interface IConstantes o exemplo não funcionará, mas você pode usar o tutorial como base para a sua integração.
    Por favor mandem sugestões e feedback's se este tutorial tem ajudado ou mesmo se estiver difícil de entender (claro que dentro de seus conhecimentos de programação Java).

    4.1 Para entender mais
    Você pode fazer a integração com outras linguagens de programação com o Mantis , não especificamente com o Selenium. Na verdade essa é uma implementação em Java para qualquer aplicação desenvolvida em Java, não específica para o Selenium. O que fiz foi inserir dentro do código do Selenium a integração!

    Para saber mais da API Java utilizada para a comunicação com o Mantis acesse:

    4.2 Fontes deste tutorial
    Arquivo zipado contendo o projeto desenvolvido no Eclipse:
    http://www.eliasnogueira.com/arquivos_blog/selenium/integracao/mantis/mantis-selenium-example.zip

    Em breve sai o projeto com a integração em conjunto do Mantis e do Testlink!
    Abraço a todos!