#TDC2010
Código sem testes é
código já quebrado
quando foi planejado
  -- Jacob Kaplan-Moss
  um dos criadores do django
Estamos em 2010
2010 > 1960
2010 > 1999
Alguma buzzword "ágil"
você tem que estar
usando
Buzzwords são
quintessenciais
Buzzwords trazem sinergia viral e o
empowerment das melhores práticas para a
cauda longa
3 anos atrás
equipe: >40 pessoas numa mesma sala
escopo: Webapp em Tomcat
buzzwords: Bodyshop típico: cmms.. (<
1999)
2.5 anos atrás
equipe: 5 pessoas espalhadas pelo mundo
escopo: Modificações no nível de uma distro
buzzwords: Scrum, cultu...
5 > 40
Metodologias ágeis:
Extreme Programing(XP)
Scrum
Kanban
Feature Driven Develelopment (FDD)
Práticas ágeis:
Test Driven Development (TDD)
Behavior Driven Development (BDD)
Code refactoring
Continuous Integration
Pa...
TDD
Sustentável
Fácil
Não depende da gerência
TDD não é díficil.
Díficil é não fazer
quando voce
acostuma
Então, chega de
desculpas:
Eu não sei nada
sobre testes
O ecossistema de
testes no python
 • Tipos
 • Sabores
 • TestRunners
Tipos de testes
Doctest
def add(a,b):
  """
  testa a soma
  >>> add(1,2)
  3
  """
  return a + b
Unittest
unittest.TestCase
django.test.TestCase
django.test.TestCase
from django.test import TestCase

class SimpleTest(TestCase):
  def test_adicao(self):
    """
    Te...
Sabores de testes
Unitários
Nível de função

 self.assertTrue(add(1,2),3)
Integração
Entre Módulos

 r = self.client.get('/foo')
 self.assertRedirects(r,'/login/')
 self.client.login(user_name='fo...
De Regressão
Correção de erros
TestRunners
Acha e Roda os testes

 • Padrão
 • py.test
 • nose
 • outros
Meu estilo

 • Django.test.TestCase
 • Unitário
    Um TestCase por modelo
    Um ou mais testes por função
• Integração
    Um por TestCase por conjunto de apps
• Regressão
    Um teste por erro
• nose / django-nose
    Acha test...
Eu não preciso de
testes
automatizados
Código evolve
Se o seu código não
tem testes refatorar ele
é um pesadelo
Imagina isso
$ cat   `find . | grep "py$" 
          | grep -v migration` | wc -l
47260
Agora isso:
$ cat   `find . | grep "py$" 
          | grep test` | wc -l
34108
Tranquilidade de
refatorar
Felicidade é um código com boa cobertura
Eu meio que não
sei o que é TDD
Ciência da computação
é tanto sobre
computadores quanto
como a astronomia é
sobre telescópios
  -- E W Dijkstra
Test Driven
Development é tanto
sobre testes assim
quanto a ciência da
computação é sobre
computadores
TDD é sobre
desenvolvimento e
qualidade
Testes são um
subproduto
TDD
TDD
Só escreve código quando testes falham
TDD
Só escreve código quando testes falham
Só escreve testes quando testes passam
Eu nunca fiz
muitos testes no
Django
Como fazer: Instala o
django
$ easy_install pip
$ pip install django
Cria o projeto
$   django-admin.py startproject foobar
$   cd foobar/
$   chmod +x manage.py
$   vi settings.py
settings.py
import os
PROJECT_PATH = os.path.abspath(
                    os.path.split(__file__)[0])
DATABASES = {'defaul...
Hora de testar
./manage.py test

------------------------------------
Ran 0 tests in 0.000s

OK
Destroying test database '...
TDD
Só escreve código quando testes falham
Só escreve testes quando testes passam
Passou
Escreve testes
Mais Testes, então
./manage.py startapp forum
cd forum/
Meu estilo (v.2)
rm tests.py
mkdir tests
touch tests/__init__.py
touch tests/test_models.py
vi tests/test_models.py
#coding:utf8
from django.test import TestCase

class ModelTest(TestCase):
Teste de importação
def test_existe(self):
  """ O topico esta la? """
  try:
    from foobar.forum.models import Topico
 ...
Inclui a app no projeto
INSTALLED_APPS = (
    ...
    'foobar.forum',
)
Testa
./manage.py test

------------------------------------
Ran 0 tests in 0.000s

OK
Destroying test database 'default'....
0 testes!
nose
Acha testes para você sem que você tenha
que por eles no __init__.py
Dá pra chamar o pdb no ponto em que falha
( --pd...
django-nose
$ pip install nose
$ pip install django-nose
$ pip install NoseNotify #opcional
settings.py
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

INSTALLED_APPS = (
    ...
    'south', # migracoes
    'djan...
Testa de novo
F
====================================
FAIL: O topico esta la?
------------------------------------
Tracebac...
TDD
Só escreve código quando testes falham
Só escreve testes quando testes passam
Falhou
Escreve código
vi forum/models.py
class Topico(models.Model):
    """representa um topico"""
    pass
testa
.
------------------------------------
Ran 1 test in 0.014s
Pera!
Voce gastou 8 slides para escrever um
pass?
Mas TDD é muito
lento
e por lento eu
quero dizer chato
A primeira vez é
lento
Entenda o que você
esta testando
try:
  from foobar.forum.models import Topico
except ImportError:
  self.fail('Nao existe...
Não teste a framework
Teste a lógica da sua applicação
Facilitadores
Continous testing
Toda vez que você salva um arquivo ele
rerola os testes
django test extensions
Faz isso para você
Ainda é um pouco tosco
django-test-extensions
$ pip install django-test-extensions
settings.py
INSTALLED_APPS = (
    ...
    'south', # migracoes
    'django_nose', # depois do south
    'test_extensions'...
Rodando o servidor
 $ ./manage.py runtester

ou ainda

 $ ./manage.py runtester forum
Automagicamente
nosetests --verbosity 1 --with-notify forum
.....
-------------------------------------------
Ran 5 tests ...
Bonus combo
django-test-extensions com NoseNotify
Mas eu não
conheco todas as
assertions
Bico
Modo mais fácil:
no ./manage shell (com ipython instalado)

 >>> from django.test import TestCase
 >>> In [2]: TestCase.as...
asserts
TestCase.assert_                 TestCase.assertAlmostEqual
TestCase.assertAlmostEquals      TestCase.assertContai...
Asserts básicas
Essas você deve usar bastante

 assertTrue(True)
 assertFalse(False)

 assertEqual(1,1)
 assertNotEqual(1,...
Asserts amigáveis
Essas facilitam a vida para testes funcionais

 assertContains(response,texto,status)
 assertNotContains...
exemplo
def test_welcome(self):
  resp = self.client.get('/',{})
  self.assertContains(resp,'<h1>Oi</h1>'
                ...
Asserts amigáveis
(cont)
assertRedirects(response,nova_url)
assertTemplateUsed(response,template)
assertTemplateNotUsed(re...
WTF?
assertAlmostEqual

assertNotAlmostEqual
Não quase iguais?
a = 1.21
b = 1.22
#sao iguais ate a primeira casa
self.assertAlmostEqual(a,b,1)
#diferentes depois da se...
Asserts que eu não uso
assertRaises
Testo assim:
try:
    foobar.bang():
    self.fail('Bang tem que explodir')
except ExplodingException:
    pass
Agora é tarde
demais para TDD,
meu projeto já
existe
Pera! Olha só

 • Testes de Regressão
 • django_test_utils
Seu melhor amigo
Garante que um erro que aconteceu nunca
mais volte a acontecer
Usado por todos os grandes projetos de
sof...
Testes de Regressão
Encontrou um erro
[24/Jul/2010 11:14:51] "GET / HTTP/1.1" 404 1946
Escreve um teste que
falha por causa do erro
$ vi forum/test_regression.py
cont
#coding:utf8
from django.test import TestCase

class TestRegression(TestCase):
    """testes de regressao"""
cont+=1
def test_regress_home(self):
  """Home precisa existir"""
  r = self.client.get('/', {})
  self.assertEqual(r.stat...
Testa e falha
..E
================================================
ERROR: Home precisa existir
---------------------------...
Corrige o erro
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('',
    ...
    (r'^$', d...
Roda os testes e passa
nosetests --verbosity 1
....
-----------------------
Ran 4 tests in 0.025s

OK
Garantia que erros
antigos não vão
retornar para te
assombrar
Toda vez que eu
começo com TDD
mas acabo
desistindo no meio
2 formas
sustentáveis para
começar e
continuar com
TDD
Primeiro:
TDD:Eu queria ter isso
Você escreve nos testes a API que você
queria ter
Eu queria que fosse
assim:
def test_metodos(self):
  topico = Topico()
  self.assertTrue(hasattr(topico, 'titulo'))
  self...
Testa
F.
=================================================
FAIL: test_metodos (test_forum.TestForum)
---------------------...
Implementa
class Topico(models.Model):
  """representa um topico"""
  titulo = models.CharField(max_length=64)
class Respo...
Testa
..
--------------------------------------------------
Ran 2 tests in 0.002s

OK
Prós e Cons

 • Não é exatamente TDD
 • Funciona
 • Mais rápido
 • Você está perdendo cobertura
Segundo: SDT
SDT
Eu não faço TDD eu faco Stupidity-driven
testing. Quando eu faco algo estúpido, eu
escrevo um teste para garantir que ...
Em suma
Escreve código para solucinar um problema
Se o código quebrar de alguma forma besta
Escreve um teste para isso nun...
Prós e Cons

 • Não é TDD
 • Funciona mas beira Cowboyismo
 • Cobertura só sobre o código mais frágil
 • Lembra teste de r...
Por que lembra um
teste de regressão?
Porque é.
São testes de regressão para você mesmo.
Escrever testes é
mais complicado
que o problema
Longo sim, complicado
não
Especialmente longo para testes funcionais
django_test_utils,   o   utlimo   bastião   dos
pregu...
django-test-utils
$ pip install django-test-utils
settings.py
INSTALLED_APPS = (
    ...
    'south', # migracoes
    'django_nose', # depois do south
    'test_extensions'...
Você começa o servidor
$ ./manage.py testmaker -a forum
Cria testes para você
Handling app 'forum'
Logging tests to foobar/forum/tests/forum_testmaker.py
Appending to current log...
Quando você termina
$ cd forum/tests
$ ls forum*
forum_testdata.serialized
forum_testmaker.py
Testes gerados
def test_forum_127958317459(self):
  r = self.client.get('/forum/', {})
  self.assertEqual(r.status_code, 2...
Não, não! Escrever
testes é mais
complicado que o
problema, mesmo!
Mocks e Stubs
Minta
descaradamente
para seu código
Imagina algo assim:
def calcula_queijo(request):
    sanduba = request.session["sanduba"]
    ....
Upcoming SlideShare
Loading in …5
×

TDD em django sem desculpas versao fisl

2,590 views

Published on

Palestra apresentada no fisl11 sobre TDD em django

Published in: Technology
2 Comments
8 Likes
Statistics
Notes
  • Glad you liked it! I'm trying to update the slides to the TDC ones but slideshare is not helping..
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • awesome presentation, I see that on #TDC2010
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
2,590
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
55
Comments
2
Likes
8
Embeds 0
No embeds

No notes for slide

TDD em django sem desculpas versao fisl

  1. 1. #TDC2010
  2. 2. Código sem testes é código já quebrado quando foi planejado -- Jacob Kaplan-Moss um dos criadores do django
  3. 3. Estamos em 2010
  4. 4. 2010 > 1960
  5. 5. 2010 > 1999
  6. 6. Alguma buzzword "ágil" você tem que estar usando
  7. 7. Buzzwords são quintessenciais Buzzwords trazem sinergia viral e o empowerment das melhores práticas para a cauda longa
  8. 8. 3 anos atrás equipe: >40 pessoas numa mesma sala escopo: Webapp em Tomcat buzzwords: Bodyshop típico: cmms.. (< 1999)
  9. 9. 2.5 anos atrás equipe: 5 pessoas espalhadas pelo mundo escopo: Modificações no nível de uma distro buzzwords: Scrum, cultura de testes, sprints, entregas semanais
  10. 10. 5 > 40
  11. 11. Metodologias ágeis: Extreme Programing(XP) Scrum Kanban Feature Driven Develelopment (FDD)
  12. 12. Práticas ágeis: Test Driven Development (TDD) Behavior Driven Development (BDD) Code refactoring Continuous Integration Pair Programming Planning poker
  13. 13. TDD Sustentável Fácil Não depende da gerência
  14. 14. TDD não é díficil. Díficil é não fazer quando voce acostuma
  15. 15. Então, chega de desculpas:
  16. 16. Eu não sei nada sobre testes
  17. 17. O ecossistema de testes no python • Tipos • Sabores • TestRunners
  18. 18. Tipos de testes
  19. 19. Doctest def add(a,b): """ testa a soma >>> add(1,2) 3 """ return a + b
  20. 20. Unittest unittest.TestCase django.test.TestCase
  21. 21. django.test.TestCase from django.test import TestCase class SimpleTest(TestCase): def test_adicao(self): """ Testa que a adicao de 1 + 1 da 2. """ self.assertEqual(1 + 1, 2)
  22. 22. Sabores de testes
  23. 23. Unitários Nível de função self.assertTrue(add(1,2),3)
  24. 24. Integração Entre Módulos r = self.client.get('/foo') self.assertRedirects(r,'/login/') self.client.login(user_name='foo' ,password='bar') r = self.client.get('/foo') self.assertEquals(r.status_code,200)
  25. 25. De Regressão Correção de erros
  26. 26. TestRunners Acha e Roda os testes • Padrão • py.test • nose • outros
  27. 27. Meu estilo • Django.test.TestCase • Unitário Um TestCase por modelo Um ou mais testes por função
  28. 28. • Integração Um por TestCase por conjunto de apps • Regressão Um teste por erro • nose / django-nose Acha testes
  29. 29. Eu não preciso de testes automatizados
  30. 30. Código evolve
  31. 31. Se o seu código não tem testes refatorar ele é um pesadelo
  32. 32. Imagina isso $ cat `find . | grep "py$" | grep -v migration` | wc -l 47260
  33. 33. Agora isso: $ cat `find . | grep "py$" | grep test` | wc -l 34108
  34. 34. Tranquilidade de refatorar Felicidade é um código com boa cobertura
  35. 35. Eu meio que não sei o que é TDD
  36. 36. Ciência da computação é tanto sobre computadores quanto como a astronomia é sobre telescópios -- E W Dijkstra
  37. 37. Test Driven Development é tanto sobre testes assim quanto a ciência da computação é sobre computadores
  38. 38. TDD é sobre desenvolvimento e qualidade
  39. 39. Testes são um subproduto
  40. 40. TDD
  41. 41. TDD Só escreve código quando testes falham
  42. 42. TDD Só escreve código quando testes falham Só escreve testes quando testes passam
  43. 43. Eu nunca fiz muitos testes no Django
  44. 44. Como fazer: Instala o django $ easy_install pip $ pip install django
  45. 45. Cria o projeto $ django-admin.py startproject foobar $ cd foobar/ $ chmod +x manage.py $ vi settings.py
  46. 46. settings.py import os PROJECT_PATH = os.path.abspath( os.path.split(__file__)[0]) DATABASES = {'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': '/tmp/foobar.db', } } TEMPLATE_DIRS = ( os.path.join(PROJECT_PATH,'templates'), )
  47. 47. Hora de testar ./manage.py test ------------------------------------ Ran 0 tests in 0.000s OK Destroying test database 'default'...
  48. 48. TDD Só escreve código quando testes falham Só escreve testes quando testes passam
  49. 49. Passou Escreve testes
  50. 50. Mais Testes, então ./manage.py startapp forum cd forum/
  51. 51. Meu estilo (v.2) rm tests.py mkdir tests touch tests/__init__.py touch tests/test_models.py
  52. 52. vi tests/test_models.py #coding:utf8 from django.test import TestCase class ModelTest(TestCase):
  53. 53. Teste de importação def test_existe(self): """ O topico esta la? """ try: from foobar.forum.models import Topico except ImportError: self.fail('Nao existe topico')
  54. 54. Inclui a app no projeto INSTALLED_APPS = ( ... 'foobar.forum', )
  55. 55. Testa ./manage.py test ------------------------------------ Ran 0 tests in 0.000s OK Destroying test database 'default'...
  56. 56. 0 testes!
  57. 57. nose Acha testes para você sem que você tenha que por eles no __init__.py Dá pra chamar o pdb no ponto em que falha ( --pdb-failures) (ou ipdb)
  58. 58. django-nose $ pip install nose $ pip install django-nose $ pip install NoseNotify #opcional
  59. 59. settings.py TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' INSTALLED_APPS = ( ... 'south', # migracoes 'django_nose', # depois do south ) NOSE_ARGS = [ '--with-notify', #'--pdb-failures', ]
  60. 60. Testa de novo F ==================================== FAIL: O topico esta la? ------------------------------------ Traceback (most recent call last): File "test_models", line 18, in test_existe self.fail('Nao existe topico') AssertionError: Nao existe topico ------------------------------------ Ran 1 test in 0.003s
  61. 61. TDD Só escreve código quando testes falham Só escreve testes quando testes passam
  62. 62. Falhou Escreve código
  63. 63. vi forum/models.py class Topico(models.Model): """representa um topico""" pass
  64. 64. testa . ------------------------------------ Ran 1 test in 0.014s
  65. 65. Pera! Voce gastou 8 slides para escrever um pass?
  66. 66. Mas TDD é muito lento
  67. 67. e por lento eu quero dizer chato
  68. 68. A primeira vez é lento
  69. 69. Entenda o que você esta testando try: from foobar.forum.models import Topico except ImportError: self.fail('Nao existe topico')
  70. 70. Não teste a framework Teste a lógica da sua applicação
  71. 71. Facilitadores
  72. 72. Continous testing Toda vez que você salva um arquivo ele rerola os testes
  73. 73. django test extensions Faz isso para você Ainda é um pouco tosco
  74. 74. django-test-extensions $ pip install django-test-extensions
  75. 75. settings.py INSTALLED_APPS = ( ... 'south', # migracoes 'django_nose', # depois do south 'test_extensions', # depois do south )
  76. 76. Rodando o servidor $ ./manage.py runtester ou ainda $ ./manage.py runtester forum
  77. 77. Automagicamente nosetests --verbosity 1 --with-notify forum ..... ------------------------------------------- Ran 5 tests in 0.457s OK Destroying test database 'default'... Creating test database 'default'...
  78. 78. Bonus combo django-test-extensions com NoseNotify
  79. 79. Mas eu não conheco todas as assertions
  80. 80. Bico
  81. 81. Modo mais fácil: no ./manage shell (com ipython instalado) >>> from django.test import TestCase >>> In [2]: TestCase.assert<tab><tab>
  82. 82. asserts TestCase.assert_ TestCase.assertAlmostEqual TestCase.assertAlmostEquals TestCase.assertContains TestCase.assertEqual TestCase.assertEquals TestCase.assertFalse TestCase.assertFormError TestCase.assertNotAlmostEquals TestCase.assertNotContains TestCase.assertNotEqual TestCase.assertNotEquals TestCase.assertRaises TestCase.assertRedirects TestCase.assertTemplateNotUsed TestCase.assertTemplateUsed TestCase.assertTrue TestCase.assertNotAlmostEqual
  83. 83. Asserts básicas Essas você deve usar bastante assertTrue(True) assertFalse(False) assertEqual(1,1) assertNotEqual(1,2)
  84. 84. Asserts amigáveis Essas facilitam a vida para testes funcionais assertContains(response,texto,status) assertNotContains(response,texto,status)
  85. 85. exemplo def test_welcome(self): resp = self.client.get('/',{}) self.assertContains(resp,'<h1>Oi</h1>' ,200)
  86. 86. Asserts amigáveis (cont) assertRedirects(response,nova_url) assertTemplateUsed(response,template) assertTemplateNotUsed(response,template) assertFormError(response,form,fields,errors)
  87. 87. WTF? assertAlmostEqual assertNotAlmostEqual
  88. 88. Não quase iguais? a = 1.21 b = 1.22 #sao iguais ate a primeira casa self.assertAlmostEqual(a,b,1) #diferentes depois da segunda casa self.assertNotAlmostEqual(a,b,2)
  89. 89. Asserts que eu não uso assertRaises
  90. 90. Testo assim: try: foobar.bang(): self.fail('Bang tem que explodir') except ExplodingException: pass
  91. 91. Agora é tarde demais para TDD, meu projeto já existe
  92. 92. Pera! Olha só • Testes de Regressão • django_test_utils
  93. 93. Seu melhor amigo Garante que um erro que aconteceu nunca mais volte a acontecer Usado por todos os grandes projetos de software livre Mesmo você não vai fazer mais nenhuma forma de teste você tem que fazer esta
  94. 94. Testes de Regressão
  95. 95. Encontrou um erro [24/Jul/2010 11:14:51] "GET / HTTP/1.1" 404 1946
  96. 96. Escreve um teste que falha por causa do erro $ vi forum/test_regression.py
  97. 97. cont #coding:utf8 from django.test import TestCase class TestRegression(TestCase): """testes de regressao"""
  98. 98. cont+=1 def test_regress_home(self): """Home precisa existir""" r = self.client.get('/', {}) self.assertEqual(r.status_code, 200)
  99. 99. Testa e falha ..E ================================================ ERROR: Home precisa existir ------------------------------------------------ Traceback (most recent call last): File "foobar/forum/tests/test_regresssion.py", line 10, in test_regress_home r = self.client.get('/', {}) ... raise TemplateDoesNotExist(name) TemplateDoesNotExist: 404.html
  100. 100. Corrige o erro from django.views.generic.simple import direct_to_template urlpatterns = patterns('', ... (r'^$', direct_to_template, {'template': 'index.html'}), ... ) $ vi templates/index.html
  101. 101. Roda os testes e passa nosetests --verbosity 1 .... ----------------------- Ran 4 tests in 0.025s OK
  102. 102. Garantia que erros antigos não vão retornar para te assombrar
  103. 103. Toda vez que eu começo com TDD mas acabo desistindo no meio
  104. 104. 2 formas sustentáveis para começar e continuar com TDD
  105. 105. Primeiro:
  106. 106. TDD:Eu queria ter isso Você escreve nos testes a API que você queria ter
  107. 107. Eu queria que fosse assim: def test_metodos(self): topico = Topico() self.assertTrue(hasattr(topico, 'titulo')) self.assertTrue(hasattr(topico, 'replies'))
  108. 108. Testa F. ================================================= FAIL: test_metodos (test_forum.TestForum) ------------------------------------------------- Traceback (most recent call last): self.assertTrue(hasattr(topico, 'titulo')) AssertionError -------------------------------------------------- Ran 2 tests in 0.002s FAILED (failures=1)
  109. 109. Implementa class Topico(models.Model): """representa um topico""" titulo = models.CharField(max_length=64) class Resposta(models.Model): '''Uma resposta no topico''' topico = models.ForeignKey(Topico, related_name='replies')
  110. 110. Testa .. -------------------------------------------------- Ran 2 tests in 0.002s OK
  111. 111. Prós e Cons • Não é exatamente TDD • Funciona • Mais rápido • Você está perdendo cobertura
  112. 112. Segundo: SDT
  113. 113. SDT Eu não faço TDD eu faco Stupidity-driven testing. Quando eu faco algo estúpido, eu escrevo um teste para garantir que eu não vou repetir isso de novo --Titus Brown pycon '07
  114. 114. Em suma Escreve código para solucinar um problema Se o código quebrar de alguma forma besta Escreve um teste para isso nunca vai acontecer de novo goto 10
  115. 115. Prós e Cons • Não é TDD • Funciona mas beira Cowboyismo • Cobertura só sobre o código mais frágil • Lembra teste de regressão
  116. 116. Por que lembra um teste de regressão? Porque é. São testes de regressão para você mesmo.
  117. 117. Escrever testes é mais complicado que o problema
  118. 118. Longo sim, complicado não Especialmente longo para testes funcionais django_test_utils, o utlimo bastião dos preguiçosos
  119. 119. django-test-utils $ pip install django-test-utils
  120. 120. settings.py INSTALLED_APPS = ( ... 'south', # migracoes 'django_nose', # depois do south 'test_extensions', # depois do south 'test_utils', # depois do south ... )
  121. 121. Você começa o servidor $ ./manage.py testmaker -a forum
  122. 122. Cria testes para você Handling app 'forum' Logging tests to foobar/forum/tests/forum_testmaker.py Appending to current log file Inserting TestMaker logging server... Validating models... 0 errors found Django version 1.2.1, using settings 'foobar.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
  123. 123. Quando você termina $ cd forum/tests $ ls forum* forum_testdata.serialized forum_testmaker.py
  124. 124. Testes gerados def test_forum_127958317459(self): r = self.client.get('/forum/', {}) self.assertEqual(r.status_code, 200) self.assertEqual( unicode(r.context["paginator"]), u"None") self.assertEqual( unicode(r.context["object_list"]), u"[<Topico: Topico object>, <Topico: Topico object>]") .....
  125. 125. Não, não! Escrever testes é mais complicado que o problema, mesmo!
  126. 126. Mocks e Stubs
  127. 127. Minta descaradamente para seu código
  128. 128. Imagina algo assim: def calcula_queijo(request): sanduba = request.session["sanduba"] ....
  129. 129. Não perca tempo Colocar algo no session do request em um test case é chato
  130. 130. Hora de mockear Existem muitas ferramentas de mock para python Escolha uma e vai fundo. Não esqueça de RTFM Eu uso o fudge
  131. 131. Instalar e usar pip install fudge
  132. 132. Seu teste import fudge ... def teste(self) request = fudge.Fake().has_attr( session={'sanduba': Sanduba() }) calcula_queijo(request)
  133. 133. Eu conserto os testes depois
  134. 134. PFFFFFFFFFF!
  135. 135. TDD não é díficil. Díficil é não fazer quando voce acostuma
  136. 136. Créditos http://www.flickr.com/photos/blue-moose/3528603529
  137. 137. Dúvidas?
  138. 138. Agradecimentos http://associacao.python.org.br/ Nos vemos na PythonBrasil[6] em Curitiba Outubro 21 a 23
  139. 139. Referências http://code.google.com/p/python-nose/ http://github.com/jbalogh/django-nose http://github.com/garethr/django-test-extensions http://github.com/ericholscher/django-test-utils http://github.com/ctb/pony-build Tdd em django sem desculpas @fractal petrich@gmail.com creative commons (by) (sa)

×