• Nenhum resultado encontrado

Django: Guia de testes

N/A
N/A
Protected

Academic year: 2021

Share "Django: Guia de testes"

Copied!
12
0
0

Texto

(1)
(2)

Django: Guia de testes

Osvaldo Santana Neto

(3)

Tweet Sobre Esse Livro!

Por favor ajude Osvaldo Santana Neto a divulgar esse livro noTwitter! O tweet sugerido para esse livro é:

Acabei de comprar o ebook ”Django: Guia de testes” do @osantana: http://j.mp/djteste A hashtag sugerida para esse livro é#django-testes.

Descubra o que as outras pessoas estão falando sobre esse livro clicando nesse link para buscar a hashtag no Twitter:

(4)
(5)

Conteúdo

Créditos . . . 1 Introdução . . . . 2 Django Tests . . . 2 O Projeto . . . 4 Primeiro Teste . . . 5

(6)

CONTEÚDO 1

Créditos

• Autor e Capa:Osvaldo Santana Neto • Foto da Capa:Fabrizio Sciami

AVISO!

Esse livro ainda está em processo de escrita, portanto, as informações aqui podem estar incorretas. Além disso a revisão de escrita (gramática, ortografia) será feita apenas na etapa final. É bem provável que você encontre erros graves de português antes disso.

(7)

Introdução

Quando comecei a trabalhar com Django encontrei algumas dificuldades na criação de testes automati-zados em meus projetos. Minhas dificuldades principais eram:

• Fazer com que os testes unitários não manipulassem o banco de dados; • Escrever testes que executassem rápido;

• Testar só o meu código e não o framework.

Com o tempo eu me desapeguei de algumas crenças que tinha no desenvolvimento de testes unitários (ex. testes unitários não devem interagir com o banco de dados) e aceitei o “Jeito Django” de testar.

Mas eu tive que aprender isso na marra porque não encontrava bons tutoriais oferecendo uma abordagem mais prática e com exemplos baseados em aplicações de verdade. Só encontrava exemplos muito básicos e completamente descolados do “mundo real”.

Vamos trabalhar com o Django 1.7 mas os exemplos devem funcionar sem maiores problemas com o Django 1.6. Você perceberá que também uso Python 3 nos exemplos.

Django Tests

A distribuição padrão do Django trás quase tudo o que é necessário para testarmos nossas aplicações e por isso vou focar nessas ferramentas.

Existe um bom conjunto de ferramentas e aplicações Django voltadas para o desenvolvimento de testes no siteDjango Packages.

Organizando os testes

Um projeto Django ideal tem as suas funcionalidades separadas em várias aplicações (applications). O modo padrão de organizar os testes de uma aplicação é criando módulos ou packages Python com nomes seguindo o formatotest*. Usaremos o formato:app/tests/test_*.py.

Dentro desses módulos você pode ter uma ou mais subclasses de umTestCasecom métodos denominados test_*onde implementaremos os cenários de testes que precisamos.

Executando os testes

(8)

Introdução 3

# Todos os testes do projeto $ ./manage.py test

# Todos os testes da aplicação "reminder"

$ ./manage.py test reminder

# Todos os testes de um TestCase específico

$ ./manage.py test reminder.tests.test_views.ViewTestCase # Apenas um teste

$ ./manage.py test reminder.tests.test_views.ViewTestCase.test_home

Dica 1

Durante o desenvolvimento de uma funcionalidade não é necessário executar o conjunto completo de testes da sua aplicação o tempo todo. Execute apenas aqueles testes relacionados diretamente com o que você está trabalhando. Deixe para executar todos os testes apenas quando você terminar a sua sessão de trabalho e antes de fazer commit/push para se certificar de que nada esteja quebrado.

Dica 2

Crie um ambiente de integração continua (Continuous Integration - CI) que execute todos os testes do seu projeto sempre que alguém enviar código novo para o respositório de código. Esse tipo de ferramenta é extremamente útil.

Tipos deTestCase

A distribuição padrão do Django disponibiliza vários tipos de classes “TestCase” mas as principais são: django.test.TestCase

Essa classe funciona de forma análoga à classeunittest.TestCaseda biblioteca padrão do Python mas adiciona alguns facilitadores:

1. Cliente: uma instância deClient()no atributoself.client. Essa instância permite que a gente simule a execução de requisições HTTP em nossa aplicação.

2. Transações: durante a execução dos testes o Django controla a execução das transações para permitir que cada teste comece sempre em um cenário de banco de dados vazios.

django.test.LiveServerTestCase

Os conjuntos de testes que herdam dessa classe colocam o servidor de desenvolvimento do Django no ar para permitir a execução de testes de interação com ferramentas para testes funcionais comoSeleniumou Splinter.

Esse tipo de teste é bem difícil de manter e, com o tempo, eles passam a ser algo que mais atrapalha do que ajuda. Eu evito esse tipo de teste porque minhas aplicações geralmente não fazem uso muito intenso de engenharia de frontend (HTML/CSS/JS). Se o seu projeto usa muito JS, por exemplo, esse tipo de teste ganha mais importância.

(9)

Introdução 4

O Projeto

Para exemplificar o desenvolvimento guiado por testes vamor criar uma aplicação de agenda/calendário (calendar) em um projeto de projeto de PIM (Personal Information Manager - Gerenciador de Informações Pessoais). Essa aplicação deve ter as seguintes características:

• Gerenciar Events (eventos) para determinado dia com hora de início e fim; • Um evento precisa começar e terminar no mesmo dia;

• Se a hora de início e de término do evento não for informada ele terá duração de um dia inteiro; • Não podemos permitir a criação de mais de um evento para o mesmo horário;

• O serviço precisa ser multiusuário (uma agenda por usuário); • Um usuário não poderá ver a agenda de outro;

• O usuário receberá um email e um SMS (via Twilio) com a antecedência informada no evento. Iniciando

Assumindo que você já tenha um ambiente virtual com Python 3 (venv) e com o Django 1.7 instalado. Vamos iniciar o nosso projeto:

$ django-admin.py startproject pim $ cd pim

$ ./manage.py startapp cal $ mkdir cal/templates/cal/

Nosso projeto deve ter uma estrutura parecida com essa: pim/ |-- cal/ | |-- migrations/ | | `-- __init__.py | |-- templates/ | | `-- cal/ | |-- __init__.py | |-- admin.py | |-- models.py | |-- tests.py <-- Testes | `-- views.py |-- pim/ | |-- __pycache__/ | |-- __init__.py | |-- settings.py | |-- urls.py | `-- wsgi.py `-- manage.py*

O comando./manage.py startappjá cria um módulotests.pymas eu prefiro organizar meus testes de um modo que me permite separar um pouco mais as coisas

(10)

Introdução 5

$ mkdir cal/tests/

$ touch cal/tests/__init__.py $ rm cal/tests.py

A aplicaçãocalvai ficar assim: cal/ |-- migrations/ | `-- __init__.py |-- templates/ | `-- cal/ |-- tests/ | `-- __init__.py |-- __init__.py |-- admin.py |-- models.py `-- views.py

Primeiro Teste

Agora que temos a estrutura básica do nosso projeto vamos fazer um teste bem básico: verificar se a página inicial está funcionando.

Vamos criar o primeiro teste: # cal/tests/test_views.py

from django.test import TestCase

class ViewTestCase(TestCase):

def test_home(self):

response = self.client.get("/")

self.assertEqual(response.status_code, 200) # 200 OK

E adicionaremos a aplicação calna nossa lista de aplicações instaladas (INSTALLED_APPS) no arquivo pim/settings.py: # pim/settings.py INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',

(11)

Introdução 6

# Project applications

'cal', )

Agora estamos prontos para executar o nosso teste: $ ./manage.py test

Creating test database for alias 'default'... F

====================================================================== FAIL: test_home (cal.tests.test_views.ViewTestCase)

---Traceback (most recent call last):

File "./pim/cal/tests/test_views.py", line 8, in test_home self.assertEqual(response.status_code, 200) # 200 OK AssertionError: 404 != 200

---Ran 1 test in 0.035s

FAILED (failures=1)

Destroying test database for alias 'default'...

E como já era esperado o nosso teste está falhando, afinal, ainda não criamos a view nem roteamos a URL para nossa páginahome. Vamos implementar a nossa view:

# cal/views.py

from django.shortcuts import render

def home(request):

return render(request, "cal/home.html")

Criar um template para ser renderizado: <!-- cal/templates/cal/home.html -->

<html> <head>

<title>Hello World!</title> </head>

<body>

<h1>Hello Django Tests!</h1> </body>

</html>

(12)

Introdução 7

# pim/urls.py

from django.conf.urls import patterns, include, url

from django.contrib import admin urlpatterns = patterns('',

url(r'^$', 'cal.views.home', name='home'), # / -> home url(r'^admin/', include(admin.site.urls)),

)

Pronto. Agora podemos executar o nosso teste novamente: $ ./manage.py test

Creating test database for alias 'default'... .

---Ran 1 test in 0.011s

OK

Destroying test database for alias 'default'... E tudo passou perfeitamente. Estamos prontos para continuar. Conclusão

Quando a gente trabalha com Test-Driven Development esses passos se repetem o tempo todo: 1. Criamos um teste;

2. Executamos para garantir que o teste falha; 3. Implementamos o código para que o teste passe;

4. Refatoramos o código garantindo que os testes continuem passando.

Dica

Se você criou um teste novo e ele passa de primeira desconfie que ele está testando algo que já foi testado ou que a implementação do teste está incorreta.

Referências

Documentos relacionados

DISTRIBUIÇÃO LTDA - EPP Dogon`s Son RJ Provido parcialmente 18289 Na Laje Filmes Produções. Ltda- ME Dona Escarola e Mister Bacon SP Não provido 18027 K.K CINEMA E VÍDEO LTDA

O Ebitda RCA consolidado aumentou €103 m face ao período homólogo (YoY) para os €487 m, suportado pelo desempenho dos negócios de E&amp;P e de R&amp;D, que mais do que

A realização da estágio em saúde coletiva realizado no Centro de Referência Especializado de Assistência Social – CREAS, no desempenho de seu caráter

RESUMO: Neste artigo, desenvolvemos uma breve análise sobre o papel do professor que atravessa o discurso materializado no Documento Base da Educação Profissional Técnica de

Sabendo-se que o tamanho e o peso das plaquetas, hemácias e leucócitos determinam o protocolo mais efetivo para concentrar plaquetas em cada espécie (LÓPEZ et al.,

» Estamos em condições de fornecer consultoria e/ou informações especializada para o estudo e/ou a definição de novos artigos ou soluções coordenadas para problemas operativos,

O Código Civil acrescentou para os cônjuges, além desses deveres, os de fidelidade recíproca e de vida em comum, no domicílio conjugal (art. 1.566), que não

Na Figura 6 é apresentado o resultado da análise termogravimétrica da camada externa da amostra do poço RP–0147, onde observamos uma perda de massa