Tabela de conteúdos
Testes
1 - Definições
Testes servem para verificar se as respostas na saída são esperadas dentro de um cenário independente dos demais. Isso pode ser feito manualmente ou de forma automatizada.
Os cenários geralmente estão presentes como histórias do usuário, dentro delas ou ainda em variações das informações tratadas.
Existem muitos cenários a serem observados que podem refletir um comportamento na aplicação, por exemplo: inexistência de alguns serviços; a quantidade de informação disponível aumenta consideravelmente; etc…
Os mesmos resultados esperados devem ser garantidos nas versões subsequentes do sistema para garantir que o sistema não regrediu nas outras funcionalidades. É importante, sempre executar uma bateria de testes a cada nova versão.
Em resumo: teste de software é o processo que visa a execução do software de forma controlada, com o objetivo de avaliar o seu comportamento, baseado no que foi especificado. A execução dos testes é considerada um tipo de validação (testes de aceitação) ou verificação (testes unitários, de integração e de sistema).
2 - Dimensões dos Testes
- Técnica - Como testar?
- caixa branca
- caixa preta
- Nível - Quando testar?
- unitário
- integração
- sistema
- aceitação
- Tipos - O que testar?
- funcionais
- carga
- regressão
- usabilidade
- desempenho
3 - Ferramentas
3.1 - Selenium
Selenium é uma ferramenta de testes que realiza o uso do sistema de forma automatizada e sequenciada como se fosse o acesso de um usuário do sistema.
Existe uma extensão para browsers onde pode-se gravar todo a navegação, incluir as verificações e salvar as sequências de teste.
3.1.1 - Selenium WebDriver
É uma API de integração entre uma linguagem de programação (PHP, Java, Python, etc…) e o driver que manipula o browser.
Um dos drivers que podemos utilizar é o Chromedriver.
3.1.2 - Selenium WebDriver + PHP = Laravel Dusk
Integração em PHP ao WebDriver para testes automatizados 1).
3.1.3 - Selenium WebDriver + Java + JUnit
Integração em Java ao Selenium WebDriver para testes automatizados
3.2 - Robot Framework
O Robot é um framework para testes escrito em Python criado pela Nokia, de código aberto, aceita a integração de várias bibliotecas, entre elas a do Selenium WebDriver.
4 - Exemplos
Nos exemplos a seguir, já teremos realizado o tutorial de Simulação do SSO e execução do ChromeDriver.
4.1 - Utilizando o WebDriver e Laravel Dusk
Os exemplos abaixo são de uma aplicação que utiliza dois perfis administrativos: administrador e inicial (root) e, alguns logins iniciais pré-cadastrados.
Esse login inicial pode criar administradores ou outro perfil inicial.
a. Acesso de Usuário com perfil Inicial
Cenário: Acesso Administrativo US01-0: Como Administrador, quero acessar a área administrativa para que possa gerenciar o sistema
US01-0 - Passo-a-passo
- Clicar em 'Acesso Administrativo'
- Acessar o CAS
- Utilizar CPF do Administrador
- Acesso à tela de administração
... # Código em Laravel Dusk /** * @group T00 * @group US01-0 * @throws \Throwable */ public function test_Login_no_CAS() { $username = env('ADMIN_USERNAME'); $password = env('ADMIN_PASSWORD'); $this->browse( function (Browser $browser) use($username, $password) { $browser->assertSee('Acesso administrativo'); $browser->clickLink('Acesso administrativo'); $browser->type('username', $username); $browser->type('password', $password); $browser->click('button[type=submit]'); $browser->assertDontSee('Acesso administrativo'); }); } ...
b. Acesso Administrativo
# Rotinas muito utilizadas transformadas em funções abstract class DuskTestCase extends BaseTestCase { ... protected static $_cpf_invalido = [ '00000000000', '11111111111', '22222222222', '33333333333', '44444444444', '55555555555', '66666666666', '77777777777', '88888888888', '99999999999' ]; ... protected function logarAdministrativo($username, $password) { $this->browse( function (Browser $browser) use($username, $password) { sleep(1); $browser->assertSee('Acesso administrativo'); $browser->clickLink('Acesso administrativo'); $browser->type('username', $username); $browser->type('password', $password); $browser->click('button[type=submit]'); }); } protected function logarComoAdministrador() { $username = env('ADMIN_USERNAME'); $password = env('ADMIN_PASSWORD'); $this->logarAdministrativo($username, $password); } protected function logarComoRoot() { $username = env('ROOT_USERNAME'); $password = env('ROOT_PASSWORD'); $this->logarAdministrativo($username, $password); } protected function abrirMenu($menu) { $this->browse( function (Browser $browser) use($menu) { // selecionar menu root $navMobile = $browser->driver->findElement(WebDriverBy::xpath('//a[@data-target="nav-mobile"]')); if ($navMobile->isDisplayed()) { $navMobile->click(); } $browser->clickLink($menu); }); } protected function sair() { $this->browse( function (Browser $browser) { sleep(1); $browser->clickLink('Sair'); }); } ... }
Cenário: Cadastrar Administrador US06: Como Root/Administrador, quero cadastrar Administrador, para que possa gerenciar eventos Alternativos: US06-0 Cadastrar Administrador US06-1 Alterar status
US06-0 Passo-a-passo
- Logar com o perfil Root
- Acessar a lista de Administradores
- Cadastrar um Administrador
- Fazer logout do CAS
... /** * @group T01 * @group US06-0 * @group mock * @throws \Throwable */ public function test_US06_0_Cadastrar_Administrador_sendo_Root() { $this->logarComoRoot(); $this->abrirMenuRoot('Administradores'); $this->browse( function (Browser $browser) { $browser->clickLink('Cadastrar'); $browser->assertSee('Cadastro'); }); $this->browse( function (Browser $browser) { foreach (self::$_cpf_invalido as $cpf_invalido) { $browser->type('input[id="cpf"]', $cpf_invalido); $browser->assertVisible('[data-error="O campo CPF deve conter um CPF válido."]'); } }); $adminusername = env('ADMIN_USERNAME') $this->browse( function (Browser $browser) use ($adminusername) { $browser->type('input[id="cpf"]', $adminusername); $buttonSalvar = $browser->driver->findElement( WebDriverBy::xpath('//button[contains(text(), "Salvar")]') ); $buttonSalvar->click(); $browser->assertSee('sucesso'); }); $this->sair(); } ...
US06-1 Passo-a-passo
- Logar com o perfil Root
- Desativar o Administrador
- Fazer logout do CAS
- Acessar o CAS como o Administrador desativado
- Obter aviso 401 - não permitido
- Fazer logout do CAS
- Logar com o perfil Root
- Ativar o Administrador
- Fazer logout do CAS
... /** * @group T01 * @group US06-1 * @group mock * @throws \Throwable */ public function test_US06_1_Alterar_Status_Administrador_sendo_Root() { $adminusername = env('ADMIN_USERNAME'); // logar como root $this->logarComoRoot(); // abrir menu root 'Administradores' $this->abrirMenuRoot('Administradores'); // desativa o usuário $this->browse( function (Browser $browser) { $buttonDeactivate = $browser->driver->findElement( WebDriverBy::xpath( '//td[contains(text(),"'.$adminusername.'")]/parent::*//a[contains(@href, \'/activate\')]' ) ); $buttonDeactivate->click(); $browser->assertSee(' desativado '); }); $this->sair(); // tenta logar com o login desativado $this->logarComoAdministrador(); $this->browse( function (Browser $browser) { $browser->assertSee('Erro 401'); sleep(1); // forçar logout $browser->visit(env('APP_URL').'/admin/logout'); }); // reativar usuário $this->logarComoRoot(); $this->abrirMenuRoot('Administradores'); $this->browse( function (Browser $browser) { $buttonActivate = $browser->driver->findElement( WebDriverBy::xpath( '//td[contains(text(), "'.$adminusername.'")]/parent::*//a[contains(@href, \'/activate\')]' ) ); $buttonActivate->click(); $browser->assertSee(' ativado '); }); $this->sair(); } ...
4.2 - Utilizando o WebDriver e Java com JUnit
Disponível projeto no GIT avades-selenium-tests
Anexo: Exemplos utilizando o Robot Framework + Selenium
Para utilizar o Robot Framework de forma mais prática, podemos criar uma imagem docker com a instalação do framework que pode ser baixada pelo git.
Nessa imagem foram instalados as bibliotecas do framework para Selenium e Selenium2.
O arquivo com extensão .robot
2) é dividido em três seções.
*** Settings *** *** Variables *** *** Test Cases *** *** Keywords ***
Settings: Carregamento de bibliotecas, chamada a arquivos inicialização de variáveis ou funções ou com funções em Python.
Variables: Inicialização de variáveis do script
Test Cases: Métodos com os testes
Keywords: Outras funções utilizadas pelos testes
A indentação e o espaçamento definem o cabeçalho da função os parâmetros passados como argumentos.
Algumas marcações envoltas por colchetes definem argumentos, retornos, etc.
Exemplos
Exemplos no sistema NovoConhecendo a UFRJ
├── 00__acesso_administrativo.robot ├── 01__cadastrar_administrador.robot ├── 02__cadastrar_evento.robot ├── 03__cadastrar_instituicao_de_ensino.robot ├── 04__listar_inscricoes.robot ├── 05__gerenciar_inscricoes.robot └── config ├── common.robot ├── functions.py ├── keyword.robot └── variables.py
- 0*__*.robot Testes por história de usuário
- common.robot Funções mais utilizadas dentro dos testes
- functions.py Funções em Python
- keyword.robot Outras funções declaradas
- variables.py Variáveis em Python