3.4 Teste Funcional com UnitTest
O Selenium é uma ferramenta capaz de simular as ações dos usuários em aplicações Web. Desse modo, ele pode e será utilizado por nós na escrita dos chamados Testes Funcionais, ou seja, testes que executam as funcionalidades do sistema.
Considerando a Pirâmide de Teste apresentada na Seção 2.3, classificamos os testes funcionais como sendo testes do topo da piramide, ou seja, testes funcionais são considerados aqui testes de sistema ou testes fim-a-fim.
Percival (2017) prega que os testes funcionais devem, na verdade, descrever histórias do usuário, sendo, os testes, um artefato a mais para se compreender as funcionalidades que o sistema deve possuir. Ele defende que as histórias sejam incluídas como comentários no teste funcional. Por exemplo, considerando o TDD e as metodologias ágeis, é comum se falar em produto mínimo viável (do Inglês - MVP - Minimal Viable Product). O MVP corresponde ao artefato mais simples que possamos construir e que seja viável.
A aplicação que será utilizada para isso será uma lista de tarefas. Nesse sentido, uma lista de tarefas mínima, conforme descrito por Percival (2017), deve permitir ao usuário inserir itens referentes a tarefas e posteriormente, ser lembrado das tarefas a serem executadas.
Considerando o teste funcional feito anteriormente (functional_tests.py
), poderíamos editá-lo para representar uma história inicial, conforme abaixo.
Observa-se que os comentários são utilizados para descrever a história e, algumas partes deles já são implementadas como teste.
Vamos executar esse teste? Já sabemos antecipadamente o resultado do mesmo, correto? Ele irá falar. Isso é o que Percival (2017) classifica como uma falha esperada, ou seja, como o sistema ainda não implementa a funcionalidade desejara, o teste deveria falar.
Executando o Teste
Para executar esse teste, primeiramente precisamos inicializar o django para, em seguida, executar o teste. Assumindo que não temos terminais abertos, executaremos, inicialmente os comandos abaixo para inicializar o django.
Em seguida, para executar os testes, devemos abrir um novo terminar e executar os comandos abaixo:
Como será observado, o teste faz com que a janela do Firefox abra com o conteúdo abaixo e, desse modo, como o título não contém a palavra To-Do, o teste apresenta uma mensagem de erro no prompt, conforme mostrado nas linhas de 5 a 8 da saída exibida na mensagem acima.
Antes de continuar, como fizemos alterações importantes no nosso arquivo functional_tests.py
, tais alterações merecem ser confirmadas no nosso Git. Para isso, podemos executar os comandos abaixo:
Para enviar as alterações para o Github basta usar os comandos abaixo, considerando seu login e token de usuário do GitHub.
Módulo UnitTest
Alguns aspectos com o nosso caso de teste chamam atenção e merecem ser melhorados. Um deles é o fato da janela do navegador ficar aberta após o término do caso de teste. O ideal seria que a mesma fosse fechada. Para nos auxiliar nessa e em outras tarefas, vamos utilizar um dos diversos frameworks para a execução automática de testes em Python. Nesse caso, faremos uso do módulo unittest.
O trecho de código abaixo, ilustra as alterações feitas no nosso caso de teste para torná-lo aderente ao framework unittest. Os detalhes das alterações são explicados a seguir.
O primeiro ponto a ser observado é que no unittest
, os testes são organizados dentro de uma classe que herda de unittest.TestCase
(linha 4).
Um teste propriamente dito, é um método dentro dessa classe cujo nome se inicia por test_
, como ocorre em test_can_start_a_list_and_retrieve_it_later
(linha 12). Podemos ter vários métodos iniciando com test_
dentro da mesma classe e é sempre bom dar nomes significativos para os testes para auxiliar na identificação de seus objetivos.
Existem dois métodos especiais presentes na nossa classe de test: setUp
e tearDown
. Eles servem para executar ações sempre antes e após a execução de cada teste, respectivamente. No caso, dentro do setUp
nós estamos inicializando o navegador (linhas 6 e 7) e no tearDown
encerramos sua execução (linhas 9 e 10). Recordando a terminologia de casos de teste apresentada durante o curso, ao utilizar tais métodos, a intenção é tornar cada caso de teste independente pois iremos reiniciar o estado do sistema sempre, antes da execução de cada novo teste.
Para verificar se o texto desejado aparece no título do navegador estamos utilizando o método self.assertIn
, disponível no framework (linha 21). Além dele, o framework também disponibiliza outros métodos de verificação como assertEquals
, assertTrue
, dentre outros. Uma lista completa dos métodos de verificação pode ser encontrada na página do framework, disponível em https://docs.python.org/3/library/unittest.html#assert-methods.
O método self.fail
faz o teste falhar (linha 22), independentemente de qualquer outras verificação de sucesso realizada. Está sendo usado apenas como um lembrete de que o teste ainda não está finalizado e, portanto, deve falhar ao atingir esse ponto.
Finalmente, o código if __name__ == '__main__'
(linha 50) é a forma que o Python utiliza para identificar que um determinado programa é invocado via linha de comando para, então, executar o método principal do unittest.main
.
Ao executar novamente o caso de teste veremos a diferença de comportamento, principalmente com a janela do navegador abrindo e fechando rapidamente, e o resultado da execução do teste aparecendo no prompt, conforme apresentado a seguir.
No exemplo acima podemos observar que o teste falhou pois a string "To-Do" não foi encontrada no título do navegador, o qual apresenta a string padrão da execução do django; "The install worked successfully! Congratulations!"
Novamente, devido as mudanças no arquivo de casos de testes é interessante fazermos um novo commit para confirmar as alterações. No exemplo abaixo, utilizamos um git commit -a
que adiciona e confirma automaticamente todas as mudanças realizadas no repositório.
Last updated
Was this helpful?