Selenium

25
Capítulo 2 Automação de testes funcionais com o Selenium Ismayle de Sousa Santos, Pedro de Alcântara dos Santos Neto Abstract The software testing is fundamental in software quality assurance. The testing can be split according with its objective. An important testing objective is the check of the product be- havior. This kind of test is known as functional testing. However, the systematic execution of testing requires time and effort. Many times this activity is ignored. It is important the use os testing tools in order to automate this activity. Selenium is an example of this. It is free of charge and it can export the generated tests for a great variety of technologies, like PHP, Java and Ruby. This work presents the basic concept related to functional tes- ting and describes how to use Selenium integrated to Java. The work also presents good practices related to software testing that can increase productivity and reusability. Resumo O teste de software é um elemento fundamental na garantia da qualidade. Os testes po- dem ser divididos de acordo com seu objetivo. O teste funcional, por exemplo, tem por objetivo verificar o comportamento do produto desenvolvido. Contudo, a realização do teste, de forma sistemática, exige tempo e recursos, sendo por muitas vezes desconside- rado. Assim, é importante que os testadores utilizem ferramentas que automatizem de alguma forma essa atividade. O Selenium é um exemplo de ferramenta que auxilia essa atividade. Ela tem se destacado atualmente por ser gratuita e pela possibilidade de ex- portação dos testes criados a partir do seu uso para as mais variadas tecnologias, como PHP, Ruby ou Java. Este trabalho apresenta conceitos básicos do teste funcional, além de descrever como utilizar o Selenium integrado à linguagem Java. A partir dessa inte- gração serão apresentados boas práticas que podem ser aplicadas ao desenvolvimento de testes funcionais, favorecendo produtividade e reusabilidade dos testes. 2.1. Introdução No cenário atual, em que softwares estão presentes nas diversas atividades do cotidiano e no qual os sistemas estão cada vez mais voltados para web, a qualidade exigida pelos

Transcript of Selenium

Page 1: Selenium

Capítulo

2Automação de testes funcionais com o Selenium

Ismayle de Sousa Santos, Pedro de Alcântara dos Santos Neto

Abstract

The software testing is fundamental in software quality assurance. The testing can be splitaccording with its objective. An important testing objective is the check of the product be-havior. This kind of test is known as functional testing. However, the systematic executionof testing requires time and effort. Many times this activity is ignored. It is important theuse os testing tools in order to automate this activity. Selenium is an example of this. Itis free of charge and it can export the generated tests for a great variety of technologies,like PHP, Java and Ruby. This work presents the basic concept related to functional tes-ting and describes how to use Selenium integrated to Java. The work also presents goodpractices related to software testing that can increase productivity and reusability.

Resumo

O teste de software é um elemento fundamental na garantia da qualidade. Os testes po-dem ser divididos de acordo com seu objetivo. O teste funcional, por exemplo, tem porobjetivo verificar o comportamento do produto desenvolvido. Contudo, a realização doteste, de forma sistemática, exige tempo e recursos, sendo por muitas vezes desconside-rado. Assim, é importante que os testadores utilizem ferramentas que automatizem dealguma forma essa atividade. O Selenium é um exemplo de ferramenta que auxilia essaatividade. Ela tem se destacado atualmente por ser gratuita e pela possibilidade de ex-portação dos testes criados a partir do seu uso para as mais variadas tecnologias, comoPHP, Ruby ou Java. Este trabalho apresenta conceitos básicos do teste funcional, alémde descrever como utilizar o Selenium integrado à linguagem Java. A partir dessa inte-gração serão apresentados boas práticas que podem ser aplicadas ao desenvolvimentode testes funcionais, favorecendo produtividade e reusabilidade dos testes.

2.1. IntroduçãoNo cenário atual, em que softwares estão presentes nas diversas atividades do cotidianoe no qual os sistemas estão cada vez mais voltados para web, a qualidade exigida pelos

Page 2: Selenium

clientes sobre os softwares desenvolvidos se torna cada vez maior. Uma das formas maisutilizadas e recomendadas para se garantir a qualidade de software se dá a partir da re-alização de testes, visto que testes podem ser usados para revelar a presença de defeitos[Myers 2004].

O teste de software pode ser definido como a verificação dinâmica do funciona-mento de um programa, utilizando um conjunto finito de casos de teste, adequadamenteescolhido dentro de um domínio de execução, em geral infinito, contra seu comporta-mento esperado [Abran et al. 2004]. Assim, um teste, de maneira geral, envolve a execu-ção de um programa com a aplicação de certos dados de entrada, examinando suas saídas,verificando se elas combinam com o esperado e estabelecido nas suas especificações. Éimportante ressaltar que os testes não garantem que o software não contém erros, poispara isso seria necessário testar todas as entradas válidas, o que geralmente é impossível.

Ao realizarmos testes durante o desenvolvimento de software adicionamos valorao produto, uma vez que o teste corretamente executado tende a descobrir defeitos, quedevem ser corrigidos, aumentando assim a qualidade e confiabilidade de um sistema[Pressman 2006]. A falta de testes pode fazer com que o software desenvolvido sejaentregue com defeitos, o que pode trazer muitos problemas, como por exemplo, prejuízosfinanceiros, danos físicos e até perda de vidas humanas, além de prejudicar a imagem daequipe desenvolvedora perante a empresa e desta para com o cliente. Além disso, o custode não testar é muito maior, já que a identificação de erros se torna mais difícil e onerosanos estágios finais do projeto e os custos para reparação crescem em uma escala elevadacom o passar do tempo [Patton 2006].

Existem vários tipos de testes, cada um voltado para um determinado objetivo.Testes podem ser criados para verificar se as especificações funcionais estão corretamenteimplementadas (teste funcional), podendo ser executados diretamente pelos usuários fi-nais para decidir sobre a aceitação do produto desenvolvido (teste de aceitação); podemverificar se o desempenho do software está dentro do aceitável (teste de desempenho);se ele funciona sob condições anormais de demanda (teste de estresse); se o software éadequado ao uso (teste de usabilidade); testes podem ter como objetivo mostrar que osoftware continua funcionando após alguma alteração (teste de regressão); se os procedi-mentos de instalação são corretos e bem documentados (teste de instalação); para verificaro seu nível de segurança (teste de segurança); ou para verificar seu funcionamento, a partirda liberação do produto para pequenos grupos de usuários trabalhando em um ambientecontrolado (teste alfa) ou em um ambiente não controlado (teste beta) [Neto et al. 2007].

Os testes, entretanto, requerem tempo, conhecimento, planejamento, infraestru-tura e pessoal especializado, sendo, portanto, uma atividade onerosa [Myers 2004]. De-pendendo do tipo de sistema a ser desenvolvido, ela pode ser responsável por mais de 50%dos custos [Pressman 2006]. Para se ter uma idéia dos custos envolvidos, de acordo comum relatório publicado pelo NIST [NIST 2002], U$59.500.000.000,00 é o valor relativoao custo de falhas em softwares desenvolvidos nos Estados Unidos, apenas em 2002. Essemesmo relatório estima que mais de 37% desse custo (U$22.200.000.000,00) poderia tersido eliminado se a infraestrutura para teste fosse melhorada.

Uma forma de reduzir os custos da atividade de testes é a partir da automação dostestes usando alguma ferramenta apropriada. No caso dos testes funcionais, a maioria

Page 3: Selenium

das ferramentas disponíveis se baseia na gravação de todas as ações executadas por umusuário, gerando um script 1 com os passos realizados. Dessa forma, as ações gravadaspodem ser facilmente re-executadas, permitindo assim a automação do teste. Além disso,o script gerado pode ser facilmente alterado, permitindo modificações nos testes gravadossem a necessidade de re-execução do software e nova captura [Neto et al. 2007]. Comoexemplo desse tipo de ferramenta temos o Selenium-IDE [OpenQA b], que pode ser usadopara automatizar testes funcionais em aplicações web.

Neste capítulo serão apresentados alguns conceitos relacionados aos testes de soft-wares, em especial aos testes funcionais. Também serão apresentados os princípios geraisacerca dos testes e a utilização da ferramenta Selenium integrado com a linguagem deprogramação Java, a partir do uso do framework JUnit [Gamma and Beck ]. Além disso,será apresentada a ferramenta Bromine [OpenQA a], que foi criada para o gerenciamentode testes feitos com o Selenium.

2.2. Conceitos BásicosAntes de tudo, é preciso diferenciar três termos muito ligados aos testes de sofwtare: erro,defeito (bug) e falha. Um erro ocorre devido a uma ação humana que produz um resul-tado incorreto [IEEE 1990]; um defeito em um componente ou sistema pode fazer estefalhar na execução na execução de alguma funcionalidade; e uma falha corresponde auma discrepância entre o resultado ou comportamento atual (identificado durante a exe-cução dos testes) e o comportamento ou resultado esperado (definido nas especificaçõesou requisitos)[Spillner et al. 2006]. Ou seja, o ser humano está sujeito a cometer um erro(engano), que produz um defeito no código. Se um defeito no código for executado, o sis-tema falhará ao tentar fazer o que deveria (ou o que não deveria), causando possivelmenteuma falha [Müller et al. 2007].

Também é importante diferenciar “teste” de “depuração”. Testes podem demons-trar falhas que são causadas por defeitos. Depuração é a tarefa de localizar e corrigir osdefeitos [Spillner et al. 2006]. Assim, as responsabilidades de cada atividade são bemdistintas: testadores testam e desenvolvedores depuram.

Um caso de teste é uma especificação de como um software deve ser testado. Essaespecificação inclui os dados de teste, ou seja, as entradas e as saídas esperadas, e ascondições sob as quais o teste deve ocorrer. O projeto de casos de teste é um dos grandesdesafios do processo de teste de software, e pode ser tão desafiador quanto o projeto dopróprio software [Pressman 2006]. Como geralmente é impossível testar um programaexaustivamente, ou seja, testar todos os possíveis casos, o conjunto de casos de teste deveser o mais abrangente possível levando em conta qual o sub-conjunto dos casos possíveistem maior probabilidade de exibir falhas.

Um procedimento de teste é uma especificação de uma seqüência de ações paraexecução de um determinado teste. Alguns exemplos são um conjunto de passos a seremseguidos em uma interface gráfica, um conjunto de funções a serem chamadas ou umaseqüência de requisições de página para um sistema web.

Quanto a construção dos testes, existem basicamente dois métodos que podem ser

1Conjunto de instruções para um programa.

Page 4: Selenium

utilizados [Filho 2003]: (i) método da caixa branca, que objetiva determinar defeitos naestrutura interna do produto, por meio do desenho de testes que exercitem suficientementeos possíveis caminhos de execução; e (ii) método da caixa preta, que tem por objetivodeterminar se os requisitos foram total ou parcialmente satisfeitos pelo produto sem levarem conta como ocorre o processamento.

2.3. Princípios dos testesBurnstein [Burnstein 2003] define princípios, considerando o domínio da engenharia desofwtare, como sendo leis, regras ou doutrinas relativas a softwares, a maneira como sãoconstruídos e como eles se comportam. Assim, sempre que for implementar testes, otestador deve ter em mente os princípios gerais dos testes [Spillner et al. 2006]:

• Princípio 1: Testes demonstram a presença de defeitos, não a ausência. O testepode demonstrar a presença de defeitos, mas não pode provar que eles não existem.O teste reduz a probabilidade que os defeitos permaneçam em um software, masmesmo se nenhum defeito for encontrado, não prova que ele esteja perfeito.

• Princípio 2: Teste exaustivo é impossível. Testar todos os valores possíveis paratodas as entradas, efetuando todas as formas de combinação e levando em contadiferentes precondições é geralmente impossível. Na prática, na maioria das vezesos softwares requerem números astronomicamente altos de casos de testes. Assim,em vez do teste exaustivo, o testador deve levar em conta os riscos e prioridades dosistema sob teste para focar os casos dos testes.

• Princípio 3: A atividade de teste deve começar o mais cedo possível. A atividade deteste deve começar o mais breve possível no ciclo de desenvolvimento do softwaree deve ser focado em objetivos definidos.

• Princípio 4: Defeitos tendem a estar agrupados. Geralmente a maioria dos defeitossão encontrados em algumas partes do software sob teste, ou seja, é muito poucoprovável que os defeitos estejam uniformemente distribuídos pelo sofwtare.

• Princípio 5: O paradoxo do perticida. Pode ocorrer de um mesmo conjunto detestes que são repetidos várias vezes não encontrarem novos defeitos após um de-terminado momento. Para superar este “paradoxo do pesticida”, os casos de testesnecessitam ser freqüentemente revisados e atualizados. Um conjunto de testes novoe diferente precisa ser escrito para exercitar diferentes partes do software ou sistemacom objetivo de aumentar a possibilidade de encontrar mais falhas.

• Princípio 6: Testes dependem do contexto. Os testes devem ser adaptados aos riscose ambientes inerentes da aplicação. Softwares de segurança crítica, como por exem-plo o do computador de bordo de aeronaves, são testados diferentemente de soft-wares do comércio eletrônico

• Princípio 7: A ilusão da ausência de falhas. Encontrar e consertar defeitos nãoajuda se o sistema construído não atende às expectativas e necessidades dos usuários.

Page 5: Selenium

2.4. Testes funcionais de softwareO teste funcional é um teste para avaliar o quanto o comportamento observado do soft-ware está em conformidade com as especificações [Abran et al. 2004]. Isso significa queesse teste é baseado na análise da especificação de funcionalidades do software testado[Spillner et al. 2006]. Assim, o teste funcional é feito para verificar, por exemplo, se ocadastro de um novo usuário em um sítio Web funciona conforme o esperado.

Para implementar os testes de forma eficiente e evitar a construção de casos detestes desnecessários é necessário utilizar técnicas específicas para projetar os casos detestes. A seguir serão apresentadas as duas principais técnicas usadas para o desenho detestes funcionais: a particação de equivalência e a análise do valor limite.

A partição de equivalência é um método que divide o domínio de entrada emcategorias de dados. Cada categoria agrupa dados que possuem as memas característicase revelam uma classe de erros, permitindo assim, que casos de teste na mesma categoriasejam eliminados sem que se prejudique a cobertura dos testes [Filho 2003].

Em um programa de cadastro de um usuário, por exemplo, o mês do nascimentodo usuário deve estar entre 1 e 12. Com isso, as possíveis classes de equivalência paraessa entrada são: i) todos os valores inteiros menores que 1; ii) valores inteiros entre1 e 12; e iii) valores inteiros maiores que 12. Para cada uma dessas classes, qualquervalor tem, potencialmente, a mesma capacidade de detectar erros, sendo dispensável aexecução de vários testes para valores pertencentes à mesma classe de equivalência. Nãoé necessário, portanto, testar vários números negativos para verificar como a aplicação secomporta. Assim, um bom conjunto de teste para esse caso seria termos um valor menorque 1, um valor entre 1 e 12, e um valor maior que 12. O uso de outros valores seriadesnecessário, uma vez que todos os valores em uma classe de equivalência deveriam tero mesmo comportamento.

Na Análise de Valor-Limite os casos de teste são escolhidos próximo ou nas fron-teiras dos domínios de entrada, uma vez que boa parte das falhas tendem a se concentrarpróximo a esses valores. O emprego dessa técnica deve ser complementar ao uso dapartição de equivalência. Assim, em vez de selecionar um elemento aleatório de cadaclasse de equivalência, selecionam-se os casos de teste nas extremidades de cada classe[Filho 2003]. Para utilizar a técnica do Valor-Limite no exemplo anterior, devemos se-lecionar como valores representantes das partições, os valores que estão no limite entreuma classe e outra. Assim, para representar a partição de valores abaixo de 1 (um) uti-lizaríamos 0 (zero); para representar valores entre 1 e 12 utilizaríamos os números 1 e 12;e o número 13 seria o escolhido para representar valores na partição acima de 12.

2.5. Testes manuais versus Testes automatizadosUm teste manual é aquele em que o testador executa o software manualmente com basenas especificações dos testes, as quais detalham os casos e procedimentos de testes. Ostestes realizados dessa forma, em geral, são cansativos e de difícil repetição. Já os testesautomatizados, são aqueles feitos com auxilio de alguma ferramenta apropriada. Eles exi-gem mais tempo para implementar os testes, mas provêem mais segurança na manutençãoe permitem que os testes sejam executados a qualquer instante.

Page 6: Selenium

Antes de decidir em automatizar ou não os testes, é preciso analisar a aplicaçãotestada e quais testes serão contruídos. A principal razão para automação dos testes é a ne-cessidade de re-execução dos mesmos. Supondo, por exemplo, que um testador projetoucentenas de testes e optou por executá-los manualmente. Se em algum momento da exe-cução da bateria de testes2 for descoberto uma falha, então os desenvolvedores deverãoser avisados. Além disso, dependendo da falha, a execução dos testes restantes deveráser suspensa até que a mesma seja corrigida. Após a correção, como existem grandeschances de que outras partes do software sejam afetadas, o testador terá que executar to-dos os testes novamente e novas falhas podem ser encontradas repedindo o ciclo. Em umcaso típico, existe a necessidade de se executar testes centenas e até milhares de vezes.Isso normalmente justifica a automação dos testes.

A automação de um conjunto de testes geralmente demanda bem mais esforçoque sua execução manual, mas quando automatizado, sua execução é bastante simples, seatendo a execução de um script ou o clique de alguns botões [Neto et al. 2007]. Assim,em situações como a descrita, automatizar os testes é a melhor maneira de economizartempo e dinheiro.

Contudo, nem sempre é vantajoso automatizar os testes. Existem situações em querealizar os testes manualmente é mais adequado. Se a interface de usuário da aplicação formudar consideravelmente em um futuro próximo, por exemplo, então qualquer automaçãoque for feita vai precisar ser refeita. Além disso, quando o software for simples e nãohouver tempo suficiente, ou se for improvável o reuso dos testes, então o teste manualcontinua sendo uma opção a ser considerada.

2.6. A ferramenta SeleniumO Selenium é um conjunto de ferramentas OpenSource3 que pode ser usada para criaçãode testes funcionais automatizados para aplicações Web. Uma das suas vantagens é a pos-sibilidade de executar os testes em qualquer navegador com suporte a JavaScript4. Alémdisso, as ferramentas que compõem o Selenium provêem um rico conjunto de funçõesespecíficas para a implementação de testes, tais como:

• open: abre uma página usando uma URL5 que é fornecida como parâmetro;

• click/clickAndWait: executa o clique em um botão, link ou imagem;

• verifyTextPresent/assertTextPresent: verifica a presença de um texto em qualquerlugar da página;

• verifyText/assertText: verifica se um texto aparece em um determinado local;

• waitForPageToLoad : pausa uma execução do teste até que uma nova página sejacarregada. Esse comando é chamado automaticamente pelos comandos com termi-nação “AndWait”;

2Conjunto de testes.3Software de código aberto.4Linguagem de criação de scripts desenvolvida pela Netscape em 1995.5Acrônimo para Uniform Resource Locator.

Page 7: Selenium

• type: entra com um valor em um determinado campo da página;

• select: seleciona um elemento dentre uma lista de opções.

Atualmente as principais ferramentas que compõem o Selenium são: Selenium-IDE, Selenium-RC e Selenium-GRID. O Selenium-IDE é um ambiente de desenvolvi-mento integrado para construção de casos de testes. Ele opera como plug-in do FireFoxe provê interfaces amigáveis para o desenvolvimento e execução de suites de testes (con-junto de testes). O Selenium-IDE é uma ferramenta do tipo record-and-playback, ou seja,ela captura as ações executadas pelo testador e gera um script que permite a re-execuçãodas ações feitas, automatizando assim, o teste. Sua instalação é simples: basta abrir oarquivo de instalação pelo Firefox.

Apesar da facilidade de automação dos testes com o Selenium-IDE, algumas tare-fas ainda não são simples para se executar com essa ferramenta. Ele não oferece, porexemplo, suporte para testes com interação ou que devem ser executados com base emuma determinadas condições. Para esses casos deve-se utilizar o Selenium RC (Remote-Control). Este possiblita uma maior flexibilidade ao testador, permitindo a construção delógicas de teste mais complexas, a partir do uso de uma linguagem de programação. Paraisso, ele provê uma API (Application Programming Interface)6 e bibliotecas para cadauma das linguagens suportadas: HTML, Java, C#, Perl, PHP, Python, e Ruby.

O Selenium-Grid permite distribuir os testes em múltiplas máquinas, reduzindoassim o tempo gasto na execução de uma suite de testes. Ele é ideal para escalonar grandessuites de testes ou suites de testes que devem ser executadas em múltiplos ambientes.O Selenium-Grid atua executando múltiplas instâncias do Selenium-RC em paralelo deforma transparente, fazendo com que os testes não precisem se preocupar com a infra-estrutura utilizada.

Como mencionado anteriormente, o conjunto de comandos do Selenium permiterealizar uma série de ações necessárias para execução de testes em páginas web, taiscomo, entrar com valores em campos da página, selecionar itens de uma lista de opções,clicar em botões, clicar em links e realizar asserções com base nos resultados exibidos dapágina. Os comandos que realizam essas ações são divididas em três grupos:

• Actions: são comandos que geralmente causam uma mudança no estado da apli-cação. Eles representam operações realizadas pelo usuário durante a execução deum sistema web, tais como o comando “click” que indica um clique em um deter-minado botão ou link. A maioria desses comandos pode conter o sufixo “AndWait”,o que indica que a ação fez uma chamada ao servidor e que o Selenium deve esperara página carregar para executar o próximo passo.

• Accessors: examinam o estado da aplicação e armazenam o resultado em variá-veis, como o comando “storeTitle” que armazena o titulo da página em uma variá-vel determinada por parâmetro. Vale notar que as variáveis criadas no Seleniumpodem ser acessadas de duas formas: ${nomeDaVariável} ou javascriptstored-Vars[’nomeDaVariável’].

6Um conjunto de rotinas e padrões estabelecidos para a utilização das suas funcionalidades.

Page 8: Selenium

• Assertions: são como os Accessors, mas verificam se o estado da aplicação está con-forme o esperado. Todas as asserções do Selenium podem ser usadas de três modos:“assert”, “verify” e “waitFor”. Para verificar a presença de um certo texto em umdeterminado local, por exemplo, pode-se usar o comando “assertText”, “verifyText”ou “waitForText”. Com o “assert”, se a verificação falhar o teste pára, enquanto quecom o “verify” a ferramenta acusa a falha mas o teste continua executando. Já nomodo “waitFor”, que é muito útil para testar aplicações com Ajax7, o Seleniumespera o texto aparecer para prosseguir a execução.

Quanto aos parâmetros utilizados pelos comandos do Selenium, eles tipicamentesão: i) uma identificação para algum elemento da página; ii) um texto para verificar se eleaparece na página ou para colocá-lo em algum campo da página. O número de parâmetrosusados varia de acordo com o comando. Alguns exigem dois parâmetros, outros exigemsomente um, e existem aqueles que não utilizam parâmetros.

A Figura 2.1 ilustra um script de teste no formato HTML8 feito com o Selenium-IDE. Nele pode-se perceber que no formato HTML cada comando é representado comouma linha de uma tabela. Cada linha é por sua vez dividida em três células representandoo comando, o alvo e o valor, nessa ordem. O script ilustrado nesta figura, por exemplo,é formado por três comandos: o comando “open” com apenas um parâmetro, que repre-senta a URL a ser acessada (alvo); o comando “type”, com dois parâmetros, o primeirorepresentando o nome do campo a ter uma informação digitada (alvo) e o segundo con-tendo o texto que será entrado no campo (valor); e o comando “assertTextPresent”, comum parâmetro, indicando o texto (alvo) a ser procurado na página.

Figura 2.1. Script de teste do Selenium em HTML.

Nas próximas sub-seções serão apresentados o Selenium-IDE e a criação de testesautomatizados com o Selenium-RC usando a linguagem Java e o framework JUnit. AFigura 2.2 ilustra a página web que será utilizada como base para a maior parte dos scripts

7Acrônimo de Asynchronous Javascript And XML.8Acrônimo para HyperText Markup Language.

Page 9: Selenium

de testes que serão apresentados no decorrer do capítulo. Essa página é responsável pelocadastro de usuários e faz parte de um sistema de administração de um sítio que segue ummodelo específico da UFPI.

Figura 2.2. Página Web que servirá de base para os scripts de testes apresenta-dos neste capítulo.

2.6.1. Uma breve introdução ao Selenium-IDE

O Selenium-IDE, ilustrado na Figura 2.3, é um plug-in do FireFox que permite ao testadordesenvolver e executar casos de testes sem a necessidade de conhecimentos em progra-mação. Ele possui uma interface amigável e exibe o script de teste como uma tabela, setornando assim, ideal para aprender a sintaxe e o funcionamento do Selenium.

Figura 2.3. A ferramenta Selenium-IDE.

Page 10: Selenium

O menu “Arquivo” permite ao usuário criar, abrir ou salvar testes e suites de testes.O menu “Editar” contém as operações para editar os casos de testes e o menu “Opções”permite mudar as configurações da ferramenta, como por exemplo, o testador pode es-pecificar o timeout (tempo limite que a ferramenta deve esperar por uma resposta) e quallinguagem (Html, Java, Ruby, etc.) será usada para salvar os casos de testes. Logo abaixodo menu principal, pode ser especificada a UrlBase, que será compartilhada por todos ostestes, e também existem opções para controlar a execução dos casos de testes, como porexemplo, a velocidade e a forma de execução.

A ferramenta contém um menu que é exibido após o clique ou seleção de umalgum elemento da página atual. A Figura 2.4 exibe o resultado de um clique com obotão direito do mouse, sobre o texto “Inserir Usuário”, da página ilustrada na Figura 2.2.Nesse caso é exibido um menu mostrando alguns comandos do Selenium, a maioria como parâmetro alvo pré-definido de acordo com o elemento selecionado (clicado).

Figura 2.4. Menu exibido ao clicar em algum elemento da página.

Começar a construir testes com o Selenium-IDE é muito simples: basta abrir aferramenta por meio da aba “Ferramentas” do FireFox e o Selenium-IDE já começa agravar as ações que forem feitas. A Figura 2.5 ilustra o funcionamento da ferramenta, quemonta o script de teste à medida que ações vão sendo feitas pelo testador. Para encerrar agravação basta clicar no botão situado nas proximidades no canto superior direito.

O Selenium-IDE também provê flexibilidade ao construir os testes. Conformeexibido na Figura 2.6 o testador pode modificar o comando (digitando ou selecionandoalgum dentre os exibidos por meio do drop-down destacado na figura), o alvo, o valor, e

Page 11: Selenium

Figura 2.5. Gravando testes com o Selenium-IDE.

no caso de dúvidas ele pode consultar a API do Selenium na aba “Reference”, na qual asintaxe do comando selecionado é descrito. Além disso, a ferramenta permite inserir co-mentários, copiar/excluir/remover comandos, executar um único comando por vez, definironde deve começar e parar a execução.

Figura 2.6. A) Visualização da descrição dos comandos. B) Opções disponíveispara alterar o script de teste.

A localização dos elementos na página web, necessária para utilizar muitos doscomandos do Selenium (como o “type”), pode ser feita a partir de algum identificador,

Page 12: Selenium

do XPath9 do elemento, ou a partir do DOM10. No caso de um campo ou formulário,o elemento pode ser identificado por meio do seu nome ou identificador (id). Quandonão há o atributo “name” ou “id” para o elemento desejado, este pode ser localizadousando-se xPath que inicia com “//”. A expressão “//form[1]”, por exemplo, refere-seao segundo formulário da página (pois a identificação inicia do zero). Por fim, os ele-mentos da página também podem ser localizados a partir de expressões do tipo “doc-ument.forms[0].elements[3]”, a qual se refere ao quarto elemento presente no primeiroformulário da página.

O Selenium-IDE também fornece meios para tornar os testes mais fáceis de en-tender e manter. Supondo, por exemplo, que foram implementados 100 casos de testes,e que em todos eles é necessário fazer o login para acessar o sistema, então, se paralogar for preciso preencher os campos “login” e “senha”, todos os casos de testes irãose referir a esses dois elementos (identificados na página por “login” e “senha”). Agora,supondo que por algum motivo, como o uso de algum framework, o nome dos campostenha que ser alterado para “form:login” e “form:senha”. Nesse caso, todas as referênciasaos campos “login” e “senha” devem ser alterados para “form:login” e “form:senha”, re-spectivamente. Fazer essa alteração manualmente certamente exigiria muito tempo e todavez que a referência a um elemento da página fosse alterada todos os testes deveriam seratualizados.

Agora supondo que um testador que não tenha implementado os 100 testes, men-cionados acima, tenha que entendê-los para saber quais funcionalidade foram testadas,então, dependendo de como for feita a referência aos elementos da página, ele poderiaperder muito tempo tentanto identificá-los. É bom lembrar que nem sempre será possívelse referir a um elemento usando algum termo que permita a sua fácil identificação. Al-gumas vezes (e não são poucas) os elementos da página testada deverão ser localizadospelo Selenium a partir de expressões XPath do tipo “//table[@width=100]//tr[3]/td[2]//a”,o que dificulta a leitura do teste.

Assim, para tornar os testes mais legíveis e fáceis de atualizar, o testador podeusar mapeamentos utilizando JSON 11 entre nomes e os elementos da página sob teste.Isso é possível a partir do UI-Element que é um recurso suportado tanto pelo Selenium-IDE quanto pelo Selenium-RC. A Figura 2.7 ilustra à esquerda um teste feito para apágina de cadastro de usuários (ilustrado na Figura 2.2) feito no Selenium-IDE sem uti-lizar UI-Element e à direita o mesmo teste utilizando o UI-Element. Com base nela,podemos observar que utilizando o mapeamento o teste fica muito mais legível e fácilde entender. Com o script da parte B da figura é fácil perceber que o teste é feito sobrea página de cadastro de usuário, que após a preenchimento dos campos foi pressionadoo botão “Cadastrar” e que o resultado esperado é uma mensagem com o texto “UsuárioCadastrado”.

Outra vantagem da utilização do UI-Element é a fácil visualização da descriçãodos elementos. Esta é especificada a partir do mapeamento e é visível na aba “Refer-ence” após clicar em algum comando que utilize um elemento previamente mapeado.

9Acrônimo de XML Path Language.10Acrônimo de Document Object Model.11Acrônimo de JavaScript Object Notation

Page 13: Selenium

Figura 2.7. A) Exemplo de teste sem UI-Element. B) Mesmo teste da esquerdacom UI-Element.

Essas descrições tornam o teste ainda mais claro, permitindo que o mesmo seja rapida-mente compreendido. A Figura 2.8 ilustra a descrição associada ao “elemento cadas-troUsuario::mensagemExibida”, localizado no terceiro div da página (pois seu locator é“//div[2]”).

Para construir o mapeamento entre nomes e elementos basta usar um editor detextos e criar um arquivo no formato “.js” com mapeamento feito usando os comandosreconhecidos pelo UI-Element. Em seguida, esse arquivo deve ser submetido como ex-tensão do Selenium Core12 a partir do menu “Opções” do Selenium-IDE.

Os comandos que podem ser utilizados para criar o mapeamento através do UI-Element são:

• addPageSet: para adicionar uma página ou conjunto de páginas que contém oselementos que serão usados no teste. Para cada conjunto deve ser especificado onome e a descrição. Também existem outros atributos que podem ser definidos,como por exemplo, pode-se especificar uma expressão regular para indicar o pathdas páginas que pertencem ao grupo em questão a partir do atributo “pathRegex”.

• addElement: para adicionar os elementos (campos, botões, links, imagens, dentreoutros) das páginas. Deve ser definido o nome, a descrição e a localização doelemento, a qual é definida no parâmetro “locator”.

A primeira linha do mapeamento deve seguir a estrutura “var nomeDaVariavel= new UIMap()”. Mais comandos podem ser encontrados através do menu “Ajuda” do

12Componente do Selenium responsável por executar os comandos do Selenium no browser

Page 14: Selenium

Figura 2.8. Visualização da descrição dos campos por meio do UI-Element.

Selenium-IDE. A Figura 2.9 ilustra o mapeamento que foi utilizado no teste exibido naparte B da Figura 2.7. Observe que se a localização (ou forma de identificação) doselementos for alterada, basta atualizar o atributo “locator” para que todos os testes estejamatualizados. Se o endereço da página de inserção de usuário for alterado, por exemplo,então basta atualizar o atributo “pathRegex” do conjunto de página (Pageset) nomeado de“cadastroUsuario” e o atributo locator do elemento “linkUsuario” para que todos os testesda página de cadastro de usuário sejam atualizados.

Por fim, muitas vezes existem sequências de comandos que são executadas maisde uma vez em um mesmo teste. Também existem sequências de comando que são exe-cutadas em mais de teste, usando os mesmos parâmetros ou não, que podem pertencer ounão a uma mesma suite de testes. Assim, é interessante usar algum meio para agrupar taissequências, possibilitando a invocação de toda a sequência com um único comando.

Com Selenium-RC, o agrupamento de comandos pode ser facilmente feito a partirde blocos. Já para o Selenium-IDE é preciso usar o “Rollup”. A partir da definiçãodas regras de agrupamento (Rollup rules), o testador pode reunir comandos em grupospossibilitando que eles sejam invocados com o comando rollup. A parte A da Figura2.10 ilustra a definição de regras de agrupamento para reunir uma sequência de comandosem grupo identificado por “login”, que efetua o login em uma página web. A parte Bda Figura 2.10 ilustra um teste que utiliza o comando rollup para efetuar a sequência decomandos do grupo identificado por “login”.

Page 15: Selenium

Figura 2.9. Mapeamento feito para os elementos da página exibida na Figura 2.2.

A criação dos arquivos com os “Rollup rules” é feita da mesma forma que adefinição do mapeamento descrito acima, ou seja, a partir da criação de um arquivo noformato “.js” e da submissão desse arquivo como extensão do Selenium Core a partir domenu “Opções” do Selenium-IDE. Porém, nesse caso a primeira linha deve seguir a es-trutura “var nomeDaVariavel = new RollupManager()” e o único comando disponível écomando “addRollup”, usado para adicionar uma nova regra. Existem vários atributos quepodem ser definidos. No script ilustrado, o principal atributo é o getExpandedCommandso qual especifica quais serão os comandos a serem executados.

2.6.2. Escrevendo testes com o Selenium RC e a linguagem Java

Como mencionado anteriormente, com o Selenium-RC o testador pode construir testesutilizando todo o poder fornecido pela linguagem de programação utilizada. Ele pode,por exemplo, trabalhar com iterações, expressões condicionais, ler e escrever em arquivos,além de poder tratar dinamicamente os resultados dos testes.

Page 16: Selenium

Figura 2.10. A) Definição das Rollup rules. B) Teste usando o comando rollup.

O Selenium-RC é constituído de dois componentes principais: Selenium Server,ponte para o navegador, a partir do qual os comandos acionados são transmitidos e exe-cutados no navegador selecionado; Bibliotecas, conjunto de instruções que são acionadase que causam uma comunicação com o Selenium Server.

Assim, para executar testes feitos com o Selenium e alguma linguagem de pro-gramação é preciso iniciar o servidor (“selenim-server.jar”) e para que os comandos doSelenium sejam reconhecidos é necessário acrescentar a biblioteca referente a esta lin-guagem ao projeto que contém o teste.

A maneira mais fácil de iniciar a criação de testes funcionais automatizados uti-lizando Selenium e Java é criando primeiro um script (com a “estrutura” geral do teste)utilizando o Selenium-IDE. A Figura 2.11 exibe um script de teste no formato HTMLfeito com o Selenium-IDE para o cadastro de usuários da página exibida na Figura 2.2.

Observe que as cinco primeiras linhas do script exibido na figura - da abertura dapágina “/modelo/admin/index.php” até a verificação do texto “Sair” - estão associadas aologin no sistema. Isso porque para cadastrar um usuário é preciso fazer antes o login nosistema. Logo, as ações necessárias para efetuar o login também devem ser inseridas noscript de teste para que ao executar a sequência de comandos do teste se tenha acesso apágina de cadastro de usuário. É bom lembrar que o Selenium simula um usuário aces-sando a aplicação, e como o usuário deve logar para ter acesso as funções administrativasdo sistema, o teste com o Selenium também deve realizar os procedimentos necessáriospara efetuar o login.

Page 17: Selenium

Figura 2.11. Script de teste feito com o Selenium-IDE.

O próximo passo é converter script do formato HTML para Java, ou seja, converteros comandos do script nas funções disponíveis na API para a linguagem Java. Isso é feitoa partir do menu “Opções > Formato > Java (JUnit) SeleniumRC”. Caso o testador queiraexecutar os testes no TesteNG ele deve usar a opção “Opções > Formato > Java (TestNG)SeleniumRC’. O resultado da exportação, para o framework JUnit, do script ilustrado naFigura 2.11 é exibido na Figura 2.12.

Figura 2.12. Script de teste da Figura 2.11 exportado para Java (JUnit).

Após termos o arquivo Java, podemos utilizá-lo a partir do conjunto Eclipse+JUnitpara concluir a automação dos testes. Como o teste utiliza a API do Selenium para o Javaé preciso adicionar a biblioteca da API Java (selenium-java-client-driver.jar) ao projeto

Page 18: Selenium

com o teste para que os comandos sejam reconhecidos, caso contrário, eles ficarão emdestaque conforme exibido na Figura 2.13. Esse destaque indica que o comando não foireconhecido, gerando assim erro de compilação no teste.

Figura 2.13. Visualização do teste exportado no Eclipse.

O passo seguinte consiste na construção dos procedimentos de testes parametriza-dos. Para isso basta criar funções específicas reunindo os comandos de acordo com asações deles e substituir os valores utilizados por variáveis. Assim, para o script da Figura2.13, podem ser criados duas funções: login (que efetua o login na página) e cadas-troUsuario (que cadastra um usuário no sistema). Vale lembrar que é preciso instanciaruma variável do tipo Selenium para ter acesso as suas funções. Para que a instanciação doSelenium seja feita somente na classe com os casos de testes, podemos passar a variávelSelenium por parâmetro. Com isso, nossa classe com os procedimentos de teste fica comoexibido na Figura 2.14.

Em seguida, deve-se concluir a implementação dos procedimentos de testes, deforma que eles também sejam utilizados para verificar se as operações vão falhar quandodeveriam. Se no login, por exemplo, os campos login e senha não forem corretamentepreenchidos aparecerá na tela do sistema considerado uma mensagem de alerta (alert) in-dicando o erro. Assim, podemos concluir a implementação da função login acrescentandomais uma variável que armazenará o erro (mensagem do alerta) esperado. Considerandoque a mesma situação ocorre durante o cadastro de um usuário, teremos os procedimentosescritos conforme a Figura 2.15.

Por fim, resta implementar os casos de teste utilizando para isso os procedimentosde testes que foram implementados e as especificações de testes13. Na Figura 2.16 apre-sentamos alguns casos de teste criados para verificar o login e o cadastro de usuários dosistema.

13Documentos que descrevem os casos e procedimentos de testes.

Page 19: Selenium

Figura 2.14. Classe com o procedimento de teste parametrizado.

Os testes criados com o Selenium são testes que utilizam o JUnit, de forma similaraos testes de unidade. Sua execução acontece da mesma forma que os testes de unidade,clicando com o botão direito do mouse em cima da classe e solicitando sua execução viaJUnit. No entanto, existe uma diferença: para que o teste execute, é necessário que existauma instância do Selenium Server executando na mesma máquina que contém os testesque serão executados. Assim, antes de executar os testes é preciso executar o arquivoselenium-server.jar 14. Sua execução pode ser feita via comando “java -jar selenium-server.jar".

A Figura 2.17 exibe o resultado da execução dos testes apresentados neste capí-tulo. O lado A da figura apresenta a primeira execução dos testes, e no lado B a re-execução dos mesmos. Observe que no lado A da figura, a barra de execução ficou verde,indicando que nenhuma falha foi detectada, ou seja, o teste passou. Enquanto que nolado B, a barra de execução ficou vermelha pois o execução do último teste encontrouuma falha. Isso porque no último teste, no qual é feito o cadastro de um novo usuário, oresultado esperado é a mensagem “Usuário Cadastrado”. Na primeira execução da suitede testes, eles passaram porque não havia o usuário “Usuário de teste”15 cadastrado nosistema. Contudo, com a re-execução da mesma suite de teste, sem restaurar o banco dedados para o estado original, o sistema não permitiu o cadastro do mesmo usuário, nãoresultando, portanto, no resultado esperado pelo teste.

14Servidor do Selenium, que pode ser baixado no site do Selenium.15Nome do usuário contido no script de teste.

Page 20: Selenium

Figura 2.15. Classe com o procedimento de teste completo.

Vale salientar que também é possível implementar e executar casos de teste es-critos com o Selenium utilizando a linguagem Java a partir do framework TestNG. Estepor sua vez ofecere características próprias que podem ser utilizadas para facilitar a im-plementação dos testes. A escolha do framework a ser utilizado deve ser baseado nosconhecimentos da equipe de teste e nos recursos que tais ferramentas oferecem.

Assim como no Selenium-IDE, o mapeamento feito com o UI-Element tambémpode ser usado com o Selenium-RC, porém neste só é possível adicionar um arquivode mapeamento e ele deve ser chamado de “user-extensions.js” e deve estar no mesmodiretório do “selenium-server.jar”. Com isso, basta executar o servidor com o comando“java -jar selenium-server.jar -userExtensions user-extensions.js” para que o mapeamentoseja reconhecido e dessa forma o procedimento de cadastro de usuário, por exemplo, podeser escrito conforme exibido na Figura 2.18.

Page 21: Selenium

Figura 2.16. Classe com os casos de testes.

Figura 2.17. A) A execução dos testes não encontrou falhas. B) A execução dostestes encontrou uma falha.

Page 22: Selenium

Figura 2.18. Usando mapeamento de interface de usuário com o Selenium-RC.

2.7. Bromine: uma ferramenta para gerenciamento de testes SelenesesBromine é uma ferramenta que permite a fácil visualização e execução de testes usando oSelenium RC. As principais vantagens desta ferramenta se referem ao armazenando dosresultados dos testes para análises e a forma menos técnica de apresentação e execuçãodos testes, facilitando o gerenciamento dos mesmos. A Figura 2.19 exibe a tela principalda ferramenta, em que deve ser feito o login16. O processo de instalação da ferramentapode ser encontrado no site da própria ferramenta 17.

Figura 2.19. Tela principal do Bromine.

Dentre as características do Bromine estão: suporte a testes em Java e PHP; fa-cilita a execução de testes em múltiplas combinações de Sistema Operacional (S.O.) enavegador; possibilidade de executar testes com várias instâncias do Selenium Server es-palhadas por vários computadores; armazenamento de todos os comandos executados;possibilidade de criar grupos e usuários restringindo as suas permissões de acesso.

Após efetuar o login no sistema, o primeiro passo para utilizar a ferramenta éacessar o painel de controle, exibido na Figura 2.20, para criar um novo projeto. Porpadrão a ferramenta já vem com um exemplo de projeto para testes na página de busca doGoogle.

16Por padrão já vem cadastrado o usuário admin, com senha e login igual a admin.17http://wiki.openqa.org/display/BR/Installing+Bromine.

Page 23: Selenium

Figura 2.20. Painel de Controle do Bromine.

É no painel de controle que são definidos os nós (máquinas nas quais há umainstância do Selenium RC executando), os projetos, os usuários e permissões, além deoutras configurações que não são descritas aqui. Vale lembrar que no caso de só a máquinalocal ser utilizada para executar os testes deve-se adicionar um nó com o path sendo127.0.0.1:4444, indicando assim que há uma instância ativa do Selenium RC na porta4444 da máquina.

Feitas as configurações necessárias, o próximo passo é definir o planejamento dostestes. Para isso deve-se clicar no botão do canto superior direito da página para acessaro workspace, onde encontram-se os menus “Planning” e “TestLabs”. A partir do menu“Planning” pode-se especificar os requisitos e os casos de testes, e os relacionamentoentre eles, ou seja, a associação entre casos de testes e o(s) requisito(s) que eles atendem.A Figura 2.21 exibe a adição de um requisito ao projeto criado. Observe que nele éespecificado a(s) plataforma(s) onde os testes serão executados, o que vai depender daconfiguração dos nós que foram adicionados.

Figura 2.21. Especificando requisitos no Bromine.

Page 24: Selenium

A Figura 2.22 exibe a tela onde é feita a adição dos casos de testes. Além deadicionar o script do caso de teste18, pode-se descrever o que o teste faz, como tambémexiste a possibilidade de detalhar os passos do caso de teste.

Figura 2.22. Adicionando casos de testes no Bromine.

A partir do menu “TestLabs” é possível executar os scripts de testes que foramsubmetidos ao Bromine, assim como visualizar os resultados dos testes a partir de gráficosna forma de pizza.

2.8. ConclusõesA atividade de testes é essencial para garantir a qualidade dos produtos de software de-senvolvidos. Contudo, essa é uma atividade onerosa, pois exige tempo, ferramentas apro-priadas e pessoal especializado. Por conta disso, muitas vezes essa atividade só é possi-bilitada a partir do uso de ferramentas que permitam a automação dos testes. No caso dostestes funcionais para aplicações Web, a ferramenta Selenium é uma boa opção por sergratuita e por permitir o uso de linguagens de programação como Ruby ou Java.

Neste trabalho apresentamos os princípios e os principais conceitos ligados aostestes de software. Além disso, foi apresentado o Selenium-IDE e foi descrito em detalhesa automação de testes funcionais utilizando o Selenium, a linguagem de programaçãoJava e o framework JUnit. Por fim, foi feita uma breve descrição sobre o Bromine, umaferramenta que permite a distribuição da execução da suite de teste entre várias máquinas(nós), além de facilitar o gerenciamento dos testes feitos com o Selenium.

18Esse script deve estar no formato apropriado para ser reconhecido pelo Bromine, para detalhes deve-seconsultar o site http://wiki.openqa.org/display/BR/Creating+a+testscript.

Page 25: Selenium

Referências[Abran et al. 2004] Abran, A., Moore, J., Bourque, P., Dupuis, R., and Tripp, L., editors

(2004). Guide to the Software Engineering Body of Knowledge. IEEE ComputerSociety.

[Burnstein 2003] Burnstein, I. (2003). Practical Software Testing. Springer-Verlag, NewYork.

[Filho 2003] Filho, W. P. (2003). Engenharia de Software: Fundamentos, Métodos ePadrões. LTC, 2nd edition.

[Gamma and Beck ] Gamma, E. and Beck, K. Junit testing framework. Technical report,JUnit.org, http://www.junit.org/. último acesso em 10/10/2009.

[IEEE 1990] IEEE (1990). IEEE Standard Glossary of Software Engineering Terminol-ogy - IEEE Std.610.12-1990. IEEE Computer Society.

[Müller et al. 2007] Müller, T., Graham, D., Friedenberg, D., and Veendendal, E. V.(2007). Base de Conhecimento para Certificação em Teste. Foundation Level Syl-labus, 2nd edition.

[Myers 2004] Myers, G. (2004). The Art of Software Testing. John Wiley & Sons, 2ndedition.

[Neto et al. 2007] Neto, P. S., de Sousa, F. V., and Resende, R. (2007). Automação deTeste de Software. Escola Regional de Computação da SBC Ceará - Maranhão - Piaui,Fortaleza.

[NIST 2002] NIST (2002). Planning report 02-3. Technical report, National Instituteof Standards and Technology. http://www.nist.gov/director/prog-ofc/report02-3.pdf.Acessado em setembro de 2009.

[OpenQA a] OpenQA. Bromine: A web-based qa tool for selenium. Technical report,OpenQA, http://seleniumhq.org/projects/bromine/. último acesso em 10/10/2009.

[OpenQA b] OpenQA. Selenium-ide: Integrated development environment for seleniumtests. Technical report, OpenQA, http://seleniumhq.org/projects/ide/. último acessoem 10/10/2009.

[Patton 2006] Patton, R. (2006). Software Testing. Sams Publishing.

[Pressman 2006] Pressman, R. (2006). Engenharia de Software. McGraw-Hill, 6th edi-tion.

[Spillner et al. 2006] Spillner, A., Linz, T., and Schaefer, H. (2006). Software TestingFoundations. rockynook, 2nd edition.