introdução a testes

com DJANGO







Igor Leroy

Por que?



  • pra que? confio no meu código, EU GARANTO!
  • Retrabalho, retrabalho e caça aos bugs.
  • Naah... chega disso.
  • Testes devem ser obrigatórios!


cultura




  • Código simples == Fácil de testar
  • Código modularizado == Fácil de testar
  • Modularização =! Abstração

django 1.4, 1.5




project/myapp/tests.py


./manage.py test myapp

testes unitários


from django.test import TestCase
from myapp.models import Animal

class AnimalTestCase(TestCase):
    def setUp(self):
        Animal.objects.create(name="lion", sound="roar")
        Animal.objects.create(name="cat", sound="meow")

    def test_animals_can_speak(self):
        """Animals that can speak are correctly identified"""
        lion = Animal.objects.get(name="lion")
        cat = Animal.objects.get(name="cat")
        self.assertEqual(lion.speak(), 'The lion says "roar"')
        self.assertEqual(cat.speak(), 'The cat says "meow"')

testes funcionais


import unittest
from django.test import Client

class SimpleTest(unittest.TestCase):
    def setUp(self):
        self.client = Client()

    def test_details(self):
        response = self.client.get('/customer/details/')

        self.assertEqual(response.status_code, 200)

        self.assertEqual(len(response.context['customers']), 5)

tests.py



  • Um único modulo de testes é uma idéia.
  • Testes também são códigos, precisam ser modularizados.
  • Bem escrito e fácil de entender.

TEST RUNNER



DJANGO NOSE

https://github.com/jbalogh/django-nose

TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

  • O NOSE possue mais coisas legais!

TEST ENVIROnMENT



createdb -U postgres_user -h localhost test_db

python manage.py syncdb --settings myproject.test_settings
python manage.py migrate --settings myproject.test_settings

os.environ['REUSE_DB'] = "1" 

ou

REUSE_DB=1 python manage.py test

FIXTURES


='(
{
    "pk": 4,
    "model": "auth.user",
    "fields": {
        "username": "manager",
        "first_name": "",
        "last_name": "",
        "is_active": true,
        "is_superuser": false,
        "is_staff": false,
        "last_login": "2012-02-06 15:06:44",


FACTORY GIRL


FACTORY BOY

Model mommy!


https://github.com/vandersonmota/model_mommy


  • Dados em memória.
  • Se torna opcional salvar dados no DB.
  • Rápido!





from model_mommy import mommy
from family.models import Kid

kid = mommy.make(Kid)

mommy_models.py


from model_mommy.recipe import Recipe, foreign_key
from family.models import Person, Dog


person = Recipe(Person,
    name = 'John Doe',
    nickname = 'joe',
    age = 18,
    birthday = date.today(),
    appointment = datetime.now()
)

dog = Recipe(Dog,
    breed = 'Pug',
    owner = foreign_key(person)
)




e agora?



.....myapp/
...................tests/
.............................test_models.py
.............................test_views.py
.............................test_urls.py
.............................test_forms.py
.............................test_features.py

BDD!




  • Client() é uma boa idéia?
  • Testar somente nosso código python não faz nosso sistema 100% livre de bugs.
  • Precisamos testar as funcionalidades.

CAPYBARA


SPLINTER!

http://splinter.cobrateam.info





from splinter import Browser

browser = Browser()
browser.visit('http://google.com')
browser.fill('q', 'splinter - python acceptance testing for web applications')
browser.find_by_name('btnG').click()

if browser.is_text_present('splinter.cobrateam.info'):
    print "Yes, the official website was found!"
else:
    print "No, it wasn't found... We need to improve our SEO techniques"

browser.quit()




Obrigado!


Introdução a testes com Django

By Igor Leroy

Introdução a testes com Django

  • 2,136