Programação e Desenvolvimento Dirigidor por Testes
  • Programação e Desenvolvimento Dirigidor por Testes em Python
  • Autores e Agradecimentos
  • Uso do Livro
  • Contribua com o Livro
  • Licença
  • Organização do Livro
  • 1 Introdução
    • 1.1 Considerações Iniciais
    • 1.2 Configuração Inicial do Ambiente
    • 1.3 TDD Básico
      • 1.3.1 Exemplo Simples
    • 1.4 Considerações Finais
  • 2 TESTE DE SOFTWARE
    • 2.1 Considerações Iniciais
    • 2.2 Terminologia e Conceitos Básicos
    • 2.3 Fases de Teste
    • 2.4 Técnicas e Critérios de Teste
    • 2.5 Considerações Finais
  • 3 Desenvolvimento Dirigido por Teste
    • 3.1 Configuração do Ambiente
    • 3.2 Verificando o Ambiente com TDD
    • 3.3 Controle de Versão do Projeto
    • 3.4 Teste Funcional com UnitTest
    • 3.5 Teste de Unidade e a Evolução do Sistema
      • 3.5.1 Teste de Unidade de uma View
    • 3.6 Evoluindo o Teste Funcional
    • 3.7 Revisando o Processo do TDD
  • 4 TDD E BANCO DE DADOS
    • 4.1 Envio e Processamento de Requisição POST
    • 4.2 Banco de Dados no Django
  • 5 MELHORANDO E ORGANIZANDO OS CONJUNTOS DE TESTE
    • 5.1 Isolamento dos Testes Funcionais
    • 5.2 Esperas Implícitas, Explícitas e Time Sleeps
  • 6 ATACANDO O MAIOR DESAFIO DE FORMA INCREMANTAL
    • 6.1 Separando URL no Estilo REST
    • 6.2 Iterando para um Novo Design da Aplicação
    • 6.3 Refatorar Casos de Teste
    • 6.4 Separando Templates
    • 6.5 URL para Nova Lista
    • 6.6 Alterando Modelos
    • 6.7 URL Próprio para Cada Lista
Powered by GitBook
On this page

Was this helpful?

  1. 3 Desenvolvimento Dirigido por Teste
  2. 3.5 Teste de Unidade e a Evolução do Sistema

3.5.1 Teste de Unidade de uma View

Continuando com o desenvolvimento da aplicação utilizando o TDD, vamos agora criar mais um teste que irá demandar a existência de uma view verdadeira, ou seja, nossa aplicação terá que exibir algo para o usuário, efetivamente.

A alteração no nosso teste unitário (lists/tests.py) para a implementação desse incremento é dada abaixo:

from django.urls import resolve
from django.test import TestCase
from django.http import HttpRequest

from lists.views import home_page

class HomePageTest(TestCase):

	def test_root_url_resolves_to_home_page_view(self):
		found = resolve('/')
		self.assertEquals(found.func, home_page)

	def test_home_page_returns_correct_html(self):
		request = HttpRequest()
		response = home_page(request)
		html = response.content.decode('utf-8')
		self.assertTrue(html.startswith('<html>'))
		self.assertIn('<title>To-Do lists</title>', html)
		self.assertTrue(html.endswith('</html>'))

De forma resumida, o novo teste, listado entre as linhas 13 e 19, faz uma chamada para nossa home_page e assegura de que o resultado inicie com a tag '<html>' e termine com '</html>' e, além disso, encontre '<title>To-Do lists</title> na mensagem retornada.

Ao executa o teste, como era de se esperar, obtemos uma falha.

(superlists) tdd@mlp:~/superlists/superlists$ python manage.py test
Found 2 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E.
======================================================================
ERROR: test_home_page_returns_correct_html (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tdd/superlists/superlists/lists/tests.py", line 15, in test_home_page_returns_correct_html
    response = home_page(request)
TypeError: home_page() takes 0 positional arguments but 1 was given

----------------------------------------------------------------------
Ran 2 tests in 0.002s

FAILED (errors=1)
Destroying test database for alias 'default'...

Respeitando o ciclo do TDD, vamos iniciar a inclusão de código com o mínimo esforço possível para tentar fazer nosso teste passar. Desse modo, a primeira correção é fazer a função home_page receber um argumento, conforme acusado pelo erro no teste (linha 11 acima). Assim sendo, a seguir, é aprentada uma sequência de correções/reexecução dos testes, até que o teste passe por completo. Lembre-se que no TDD a intenção é sempre de tentar fazer o mínimo necessário para passar o teste.

Alteração mínima no código lists/views.py

(superlists) auri@av:~/superlists/superlists$ cat lists/views.py 
from django.shortcuts import render

# Create your views here.
def home_page(request):
	pass 

Resultado dos testes lists/tests.py

(superlists) tdd@mlp:~/superlists/superlists$ python manage.py test
Found 2 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E.
======================================================================
ERROR: test_home_page_returns_correct_html (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tdd/superlists/superlists/lists/tests.py", line 16, in test_home_page_returns_correct_html
    html = response.content.decode('utf-8')
AttributeError: 'NoneType' object has no attribute 'content'

----------------------------------------------------------------------
Ran 2 tests in 0.002s

FAILED (errors=1)
Destroying test database for alias 'default'...

Alteração mínima no código lists/views.py

Cuidando para que um objeto HttpResponse seja retornado.

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def home_page(request):
	return HttpResponse()

Resultado dos testes lists/tests.py

(superlists) tdd@mlp:~/superlists/superlists$ python manage.py test
Found 2 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F.
======================================================================
FAIL: test_home_page_returns_correct_html (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tdd/superlists/superlists/lists/tests.py", line 17, in test_home_page_returns_correct_html
    self.assertTrue(html.startswith('<html>'))
AssertionError: False is not true

----------------------------------------------------------------------
Ran 2 tests in 0.002s

FAILED (failures=1)
Destroying test database for alias 'default'...

Alteração mínima no código lists/views.py

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def home_page(request):
	return HttpResponse('<html>')

Resultado dos testes lists/tests.py

(superlists) tdd@mlp:~/superlists/superlists$ python manage.py test
Found 2 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F.
======================================================================
FAIL: test_home_page_returns_correct_html (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tdd/superlists/superlists/lists/tests.py", line 18, in test_home_page_returns_correct_html
    self.assertIn('<title>To-Do lists</title>', html)
AssertionError: '<title>To-Do lists</title>' not found in '<html>'

----------------------------------------------------------------------
Ran 2 tests in 0.002s

FAILED (failures=1)
Destroying test database for alias 'default'...

Alteração mínima no código lists/views.py

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def home_page(request):
	return HttpResponse('<html><title>To-Do lists</title>')

Resultado dos testes lists/tests.py

(superlists) tdd@mlp:~/superlists/superlists$ python manage.py test
Found 2 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F.
======================================================================
FAIL: test_home_page_returns_correct_html (lists.tests.HomePageTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tdd/superlists/superlists/lists/tests.py", line 19, in test_home_page_returns_correct_html
    self.assertTrue(html.endswith('</html>'))
AssertionError: False is not true

----------------------------------------------------------------------
Ran 2 tests in 0.002s

FAILED (failures=1)
Destroying test database for alias 'default'...

Alteração mínima no código lists/views.py

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def home_page(request):
	return HttpResponse('<html><title>To-Do lists</title></html>')

Resultado dos testes lists/tests.py

(superlists) tdd@mlp:~/superlists/superlists$ python manage.py test
Found 2 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK
Destroying test database for alias 'default'...

Nesse ponto tudo parece estar correto, mas será que já finalizamos? Que tal tentarmos executar os testes funcionais para confirmarmos se realmente encerramos um ciclo do TDD?

(superlists) tdd@mlp:~/superlists/superlists$ python functional_tests.py 
F
======================================================================
FAIL: test_can_start_a_list_and_retrieve_it_later (__main__.NewVisitorTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/tdd/superlists/superlists/functional_tests.py", line 22, in test_can_start_a_list_and_retrieve_it_later
    self.fail('Finish the test!')
AssertionError: Finish the test!

----------------------------------------------------------------------
Ran 1 test in 3.721s

FAILED (failures=1)

O resultado mostra uma falha, mas isso era apenas para lembrar que ainda precisamos continuar com essa história. O início dela, de ter uma página web com um título contendo a palavra To-Do está feito.

Para encerrar essa etapa, nada melhor do que colocarmos nossas mudanças no controle de versão.

(superlists) tdd@mlp:~/superlists/superlists$ git diff
(superlists) tdd@mlp:~/superlists/superlists$ git commit -am "Basic view now returns minimal HTML"
(superlists) tdd@mlp:~/superlists/superlists$ git push
Previous3.5 Teste de Unidade e a Evolução do SistemaNext3.6 Evoluindo o Teste Funcional

Last updated 10 months ago

Was this helpful?