Primeiras aulas do curso Selenium: Sua webapp testada de ponta a ponta em java

Selenium: Sua webapp testada de ponta a ponta em java

Testes manuais ou automatizados? - Testes manuais ou automatizados?

Estamos muito acostumados a testar nossas aplicações de maneira manual. Empresas geralmente possuem imensos roteiros de script, e fazem com que seus analistas de teste executem esses scripts incansavelmente. Mas quais os problemas com essa abordagem?

Ao longo deste curso, testaremos uma aplicação que administra uma empresa de leilões. Nela, o usuário da empresa pode adicionar novos usuários, cadastrar leilões e efetuar lances nos mesmos. Essa aplicação foi desenvolvida em Java e está pronta para ser executada. A imagem abaixo mostra a tela inicial do sistema:

A aplicação não é muito grande: possui cadastro de usuários, leilões e lances. Mas, apesar da pequena quantidade de funcionalidades, pense na quantidade de cenários que você precisa testar para garantir seu funcionamento:

Se pensarmos em todos os cenários que devemos testar, percebemos que teremos uma quantidade enorme de cenários! Quanto tempo uma pessoa leva para executar todos esses cenários? Agora imagine o mesmo problema em uma aplicação grande. Testar aplicações grandes de maneira manual leva muito tempo! E por consequência, custa muito caro!

Na prática o que acontece é que, como testar sai caro, as empresas optam por não testar! No fim, entregamos software com defeito para nosso cliente! Precisamos mudar isso!

Se removermos a parte humana do processo e fizermos com que a máquina execute o teste, resolvemos o problema: a máquina vai executar o teste rápido, repetidas vezes, e de graça!

A grande questão é: como ensinar a máquina a fazer o trabalho de um ser humano? Como fazê-la abrir o browser, digitar valores nos campos, preencher formulários, clicar em links e etc?

Para isso, faremos uso do Selenium! O Selenium é um framework que facilita e muito a vida do desenvolvedor que quer escrever um teste automatizado! Para usá-lo, faça o download do Selenium Server Standalone aqui.

Basta agora criar um projeto java qualquer (aqui vamos chamá-lo de "testes-de-sistema") e referenciar esse .jar (copie o .jar pra dentro do projeto, clique com o botão direito sobre ele e selecione Build Path -> Add Library!

A primeira coisa que uma pessoa faria para testar a aplicação seria abrir o browser. Com Selenium, precisamos apenas da linha abaixo:

WebDriver driver = new FirefoxDriver();

Nesse caso, estamos abrindo o Firefox! Em seguida, entraríamos em algum site. Vamos entrar no Google, por exemplo, usando o método get():

driver.get("http://www.google.com.br/");

Para buscar o termo "Caelum", precisamos digitar no campo de texto. No caso do Google, o nome do campo é "q".

Para descobrir, podemos fazer uso do Inspector, no Chrome (ou do Firebug no Firefox). Basta apertar Ctrl+Shift+I (ou F12), e a janela abrirá. Nela, selecionamos a lupa e clicamos no campo que queremos descobrir o nome. Ele nos levará para o HTML, onde podemos ver name="q".

Com Selenium, basta dizermos o nome do campo de texto, e enviarmos o texto:

WebElement campoDeTexto = driver.findElement(By.name("q"));
campoDeTexto.sendKeys("Caelum");

Agora, basta submetermos o form! Podemos fazer isso pelo próprio campoDeTexto:

campoDeTexto.submit();

Pronto! Juntando todo esse código em uma classe Java simples, temos:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class TesteAutomatizado {

    public static void main(String[] args) {
        // abre firefox
        WebDriver driver = new FirefoxDriver();

        // acessa o site do google
        driver.get("http://www.google.com.br/");

        // digita no campo com nome "q" do google
        WebElement campoDeTexto = driver.findElement(By.name("q"));
        campoDeTexto.sendKeys("Caelum");

        // submete o form
        campoDeTexto.submit();

    }
}

Se você não entendeu algum método invocado, não se preocupe. Estudaremos eles com mais detalhes nos próximos capítulos. Nesse momento, rode a classe! Acabamos de fazer uma busca no Google de maneira automatizada!

Execute o teste novamente. Veja agora como é fácil, rápido e barato! Qual a vantagem? Podemos executá-los a tempo! Ou seja, a cada mudança que fazemos em nosso software, podemos testá-lo por completo, clicando apenas em um botão. Saberemos em poucos minutos se nossa aplicação continua funcionando!

Quantas vezes não entregamos software sem tê-lo testado por completo? Vamos acabar com isso!

Observação: Caso esteja usando a versão nova do Selenium, será necessário configurar o GeckoDriver antes de executá-lo: System.setProperty("webdriver.gecko.driver", "ENDEREÇO DO EXECUTÁVEL DO GECKODRIVER"); O endereço do executável será algo como C:\GeckoDriver\geckodriver.exe. Caso não o tenha instalado na sua máquina, você pode baixa-lo aqui: https://github.com/mozilla/geckodriver/releases

Preenchendo e testando formulários - Preenchendo e testando formulários

Antes de começarmos a testar, precisamos fazer o download do projeto que utilizaremos ao longo do curso. Como já dito, testaremos um sistema de leilões. Mas não se preocupe, você não precisa conhecer de desenvolvimento web. A aplicação está pronta e apenas a executaremos!

Faça o download do projeto aqui. Dezipe-o em alguma pasta e, no terminal, digite a seguinte instrução dentro do diretório do projeto:

ant jetty.run

Na primeira vez, essa operação pode levar alguns minutos, pois o ant está baixando todas as dependências necessárias para rodarmos o projeto Java. Mas assim que ele terminar, nosso projeto estará rodando!

Abra o browser no seguinte endereço: http://localhost:8080. Você deve ver uma aplicação web parecida com essa:

Vamos começar a testar pela funcionalidade de cadastro de usuários! Clique em "Usuários" no menu superior. Cadastre um novo usuário, clicando no link "Novo Usuário". Preencha um nome e um e-mail qualquer:

Clique em "Salvar". O sistema devolve o usuário para a listagem com o novo usuário cadastrado:

Ótimo, aparentemente a funcionalidade está funcionando. Mas nossa experiência nos diz que futuras alterações no sistema podem fazer com que a funcionalidade pare! Vamos então automatizar um teste para o cadastro de um novo usuário. O cenário é o mesmo que acabamos de testar de maneira manual.

Vamos lá. Crie a classe "UsuariosSystemTest". Nela crie o método main():

public static void main(String[] args) {

}

A primeira parte do nosso teste manual foi entrar na página de cadastro de usuários. Sabemos que a URL é a seguinte: http://localhost:8080/usuarios/new. Vamos então fazer o Selenium abrir o Firefox nessa página:

        WebDriver driver = new FirefoxDriver();
        driver.get("http://localhost:8080/usuarios/new");

Nessa página, precisamos cadastrar algum usuário. Vamos supor o usuário "Ronaldo Luiz de Albuquerque" com o e-mail "ronaldo2009@terra.com.br". Para preencher esses valores de maneira automatizada, precisamos saber o nome dos campos de texto para que o Selenium saiba aonde colocar essa informação!

Aperte CTRL + U (no Firefox e Chrome) ou Ctrl+F12 (no Internet Explorer) para exibir o código-fonte da página. Veja que o nome dos campos de texto são "usuario.nome" e "usuario.email". Com essa informação em mãos, precisamos 1) encontrar esses elementos na página e 2) preencher com os valores que queremos:

// encontrando ambos elementos na pagina
WebElement nome = driver.findElement(By.name("usuario.nome"));
WebElement email = driver.findElement(By.name("usuario.email"));

// digitando em cada um deles
nome.sendKeys("Ronaldo Luiz de Albuquerque");
email.sendKeys("ronaldo2009@terra.com.br");

Veja o código acima. Para encontrarmos um elemento, utilizamos o método driver.findElement. Como existem muitas maneiras diferentes para encontrar um elemento na página (pelo id, nome, classe CSS, etc), o Selenium nos provê uma classe chamada By que tem um conjunto de métodos que nos ajudam a achar o elemento. Nesse caso, como queremos encontrar o elemento pelo seu nome, usamos By.name("nome-aqui").

Tudo preenchido! Precisamos submeter o formulário! Podemos fazer isso de duas maneiras. A primeira delas é clicando no botão que temos na página. Ao olhar o código-fonte da página novamente, é possível perceber que o id do botão de Salvar é "btnSalvar". Basta então pegarmos esse elemento e clicar nele:

WebElement botaoSalvar = driver.findElement(By.id("btnSalvar"));
botaoSalvar.click();

Uma outra alternativa mais simples ainda é "submeter" qualquer uma das caixas de texto! O Selenium automaticamente procurará o form na qual a caixa de texto está contida e o submeterá! Ou seja:

nome.submit();
// email.submit(); daria no mesmo!

Se tudo der certo, voltamos a listagem de usuários. Mas, dessa vez, esperamos que o usuário Ronaldo esteja lá. Para terminar nosso teste, precisamos garantir de maneira automática que o usuário adicionado está lá. Para fazer esses tipos de verificação, utilizaremos um framework muito conhecido do mundo Java, que é o JUnit. O JUnit nos provê um conjunto de instruções para fazer esses tipos de comparação e ainda conta com um plugin que nos diz se os testes estão passando ou, caso contrário, quais testes estão falhando!

Para configurar o Eclipse no nosso projeto, clique com o botão direito do mouse sobre o projeto, e vá em Build Path -> Add Libraries. Adicione JUnit em sua versão 4.

Para garantir o usuário na listagem, precisamos procurar pelos textos "Ronaldo Luiz de Albuquerque" e "ronaldo2009@terra.com.br" na página atual. O Selenium nos dá o código-fonte HTML inteiro da página atual, através do método driver.getPageSource(). Basta então verificarmos se existe o nome e e-mail do usuário lá:

boolean achouNome = driver.getPageSource().contains("Ronaldo Luiz de Albuquerque");
boolean achouEmail = driver.getPageSource().contains("ronaldo2009@terra.com.br");

Sabemos que essas duas variáveis devem ser iguais a true. Vamos avisar isso ao JUnit através do método assertTrue() e, dessa forma, caso essas variáveis fiquem com false, o JUnit nos avisará:

assertTrue(achouNome);
assertTrue(achouEmail);

Lembre-se que para o método assertTrue funcionar, precisamos fazer o import estático do método: import static org.junit.Assert.assertTrue;.

Precisamos agora encerrar o Selenium:

driver.close();

Por fim, para que o JUnit entenda que isso é um método de teste, precisamos mudar sua assinatura. Todo método do JUnit deve ser público, não retornar nada, e deve ser anotado com @Test. Veja:

@Test
public void deveAdicionarUmUsuario() {
  // ...
}

Veja que usamos o nome do método para explicar o que ele testa. Essa é uma boa prática.

Nosso método agora ficou assim:

import static org.junit.Assert.assertTrue;

import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class UsuariosSystemTest {
    @Test
    public void deveAdicionarUmUsuario() {
        WebDriver driver = new FirefoxDriver();
        driver.get("http://localhost:8080/usuarios/new");

        WebElement nome = driver.findElement(By.name("usuario.nome"));
        WebElement email = driver.findElement(By.name("usuario.email"));

        nome.sendKeys("Ronaldo Luiz de Albuquerque");
        email.sendKeys("ronaldo2009@terra.com.br");
        nome.submit();

        boolean achouNome = driver.getPageSource()
            .contains("Ronaldo Luiz de Albuquerque");
        boolean achouEmail = driver.getPageSource()
            .contains("ronaldo2009@terra.com.br");

        assertTrue(achouNome);
        assertTrue(achouEmail);

        driver.close();
    }
}

Repare na anotação @Test antes do nome do método. Isso é obrigatório caso queiramos fazer uso do JUnit. Vamos agora executar o teste. Para isso, clique com o botão direito do mouse em cima do código-fonte da classe de teste e selecione Run As -> Junit Test, e espere o Selenium executar o teste! Ao final, você deve ver uma tela de confirmação do JUnit:

Pronto! Nosso primeiro teste para a aplicação de leilão está escrito! Mãos à obra!

Melhorando nosso código de teste com Page Objects - Melhorando nosso código de teste com Page Objects

Começando deste ponto? Você pode fazer o DOWNLOAD do projeto completo do capítulo anterior e continuar seus estudos a partir deste capítulo.

Já vimos que o Selenium facilita e muito nossa vida. Com o que já sabemos hoje, podemos escrever muitos métodos de teste e testar diferentes formulários web. Precisamos agora trabalhar para que nosso código de teste não se torne mais complicado do que deveria.

Veja o método de teste abaixo:

public class UsuariosSystemTest {

    private WebDriver driver;

    @Before
    public void inicializa() {
        driver = new FirefoxDriver();
    }

    @Test
    public void deveAdicionarUmUsuario() {
        driver.get("http://localhost:8080/usuarios/new");

        WebElement nome = driver.findElement(By.name("usuario.nome"));
        WebElement email = driver.findElement(By.name("usuario.email"));

        nome.sendKeys("Ronaldo Luiz de Albuquerque");
        email.sendKeys("ronaldo2009@terra.com.br");

        nome.submit();

        assertTrue(driver.getPageSource()
        .contains("Ronaldo Luiz de Albuquerque"));
        assertTrue(driver.getPageSource()
        .contains("ronaldo2009@terra.com.br"));

    }

    @After
    public void encerra() {
        driver.close();
    }

}

O código de testes é simples de ler. Mas poderia ser melhor e mais fácil. E se conseguíssemos escrever dessa forma?


    @Test
    public void deveAdicionarUmUsuario() {

        usuarios.novo()
        .cadastra("Ronaldo Luiz de Albuquerque", "ronaldo2009@terra.com.br");

        assertTrue(usuarios.existeNaListagem(
                "Ronaldo Luiz de Albuquerque", "ronaldo2009@terra.com.br");   

    }

Veja só como o teste é bem mais legível ! É muito mais fácil de ler e entender o que o teste faz. Agora precisamos implementar. Veja que a declaração da variável usuarios foi omitida do código acima. A ideia é que essa variável representa "a página de usuários". Veja as ações que ela contém: novo() para ir para a página de novo usuário, e existeNaListagem(), que verifica se um usuário está lá.

Vamos escrever então uma classe que representa a página de listagem de usuários e contém as operações descritas anteriormente. Para implementá-las, basta fazer uso do Selenium, igual fizemos nos nossos testes até então:

class UsuariosPage {

    public void visita() {
        driver.get("localhost:8080/usuarios");
    }

    public void novo() {
        // clica no link de novo usuario
        driver.findElement(By.linkText("Novo Usuário")).click();
    }

    public boolean existeNaListagem(String nome, String email) {
        // verifica se ambos existem na listagem
        return driver.getPageSource().contains(nome) && 
                driver.getPageSource().contains(email);
    }

}

Ótimo! Veja que escrevemos basicamente o mesmo código que escrevemos anteriormente, mas dessa vez os escondemos em uma classe específica. Mas esse código ainda não funciona. Precisamos do driver do Selenium. Mas, ao invés de instanciar um driver dentro da classe, vamos receber esse driver pelo construtor. Dessa forma, ainda conseguimos fazer uso dos métodos @Before e @After do JUnit para abrir e fechar o driver e, quando tivermos mais classes iguais a essa (para cuidar das outras páginas do nosso sistema), para compartilhar o mesmo driver entre elas:

class UsuariosPage {

    private WebDriver driver;

    public UsuariosPage(WebDriver driver) {
        this.driver = driver;
    }

    public void visita() {
        driver.get("localhost:8080/usuarios");
    }

    public void novo() {
        // clica no link de novo usuario
        driver.findElement(By.linkText("Novo Usuário")).click();
    }

    public boolean existeNaListagem(String nome, String email) {
        // verifica se ambos existem na listagem
        return driver.getPageSource().contains(nome) && 
                driver.getPageSource().contains(email);
    }

}

Excelente! Já conseguimos clicar no link de Novo Usuário e já conseguimos verificar se o usuário existe na página. Falta fazer agora o preenchimento do formulário. A pergunta é: onde devemos colocar esse comportamento? Na classe UsuariosPage? A grande ideia por trás do que estamos tentando fazer é criar uma classe para cada diferente página do nosso sistema! Dessa forma, cada classe ficará pequena, e esconderá todo o código responsável por usar a página. Ou seja, precisamos criar a classe NovoUsuarioPage.

Ela será muito parecida com nossa classe anterior. Ela também deverá receber o driver pelo construtor, e expor o método cadastra(), que preencherá o formulário e o submeterá:

class NovoUsuarioPage {

    private WebDriver driver;

    public NovoUsuarioPage(WebDriver driver) {
        this.driver = driver;
    }

    public void cadastra(String nome, String email) {
        WebElement txtNome = driver.findElement(By.name("usuario.nome"));
        WebElement txtEmail = driver.findElement(By.name("usuario.email"));

        txtNome.sendKeys(nome);
        txtEmail.sendKeys(email);

        txtNome.submit();

    }

}

Ótimo! Precisamos agora chegar nesse NovoUsuarioPage. Mas quando chegamos nela? Quando clicamos no link "Novo Usuário". Ou seja, o método novo(), depois de clicar no link, precisa retornar um NovoUsuarioPage:

    public NovoUsuarioPage novo() {
        // clica no link de novo usuario
        driver.findElement(By.linkText("Novo Usuário")).click();
        // retorna a classe que representa a nova pagina
        return new NovoUsuarioPage(driver);
    }

Agora, de volta ao nosso teste, temos o seguinte código:


public class UsuariosSystemTest {

    private WebDriver driver;
    private UsuariosPage usuarios;

    @Before
    public void inicializa() {
        this.driver = new FirefoxDriver();
        this.usuarios = new UsuariosPage(driver);
    }

    @Test
    public void deveAdicionarUmUsuario() {

        usuarios.visita();
        usuarios.novo()
        .cadastra("Ronaldo Luiz de Albuquerque", "ronaldo2009@terra.com.br");

        assertTrue(usuarios.existeNaListagem(
                "Ronaldo Luiz de Albuquerque", "ronaldo2009@terra.com.br"));

    }

    @After
    public void encerra() {
        driver.close();
    }

}

Veja só como nossos testes ficaram mais claros! E o melhor, eles não conhecem a implementação por baixo de cada uma das páginas! Essa implementação está escondida em cada uma das classes específicas!

Sabemos que nosso HTML muda frequentemente. Se tivermos classes que representam as nossas várias páginas do sistema, no momento de uma mudança de HTML, basta que mudemos na classe correta, e os testes não serão afetados! Esse é o poder do encapsulamento, um dos grandes princípios da programação orientada a objetos, bem utilizada em nossos códigos de teste.

A idéia de escondermos a manipulação de cada uma das nossas páginas em classes específicas é inclusive um padrão de projetos. Esse padrão é conhecido por Page Object. Pense em escrever Page Objects em seus testes. Eles garantirão que seus testes serão de fácil manutenção por muito tempo.

Sobre o curso Selenium: Sua webapp testada de ponta a ponta em java

O curso Selenium: Sua webapp testada de ponta a ponta em java possui 51 minutos de vídeos, em um total de 31 atividades. Gostou? Conheça nossos outros cursos de Java em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Java acessando integralmente esse e outros cursos, comece hoje!

  • 1150 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 1150 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 1150 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 1150 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Procurando planos para empresas?
Acesso por 1 ano
Estude 24h/dia onde e quando quiser
Novos cursos toda semana