Ferramentas de testes em Django – Parte 2



    No post anterior, conhecemos as ferramentas default para construção de testes automatizados em Django. Acontece que você pode “sair um pouco da caixa” e usufruir de ferramentas “third-party“, que enriquecerão o seu ambiente de desenvolvimento e lhe trarão maior segurança em seus testes de software.

    splinter – Testando a sua aplicação com um navegador

    É perfeitamente possível criar testes de aceitação em Django com a TestClient e lxml. Mas vamos ser sinceros, é deveras trabalhoso “parsear” os resultados das suas views.

    Com a Splinter, uma ferramenta para testes de aplicações web, você pode automatizar ações executadas por navegadores, como visitar uma página, preencher um formulário ou clicar em um link; tudo isso sem preocupar-se com parsing, nós, DOM, nem nada do tipo:

    from splinter.browser import Browser
    browser = Browser()
    # Visitar uma URL
    url = "http://search.twitter.com"
    browser.visit(url)
    browser.fill('q', "#cobrateam") 
    
    # Procurar e clicar no botão 'search'
    button = browser.find_by_css("#searchButton input").first 
    
    # Interagir com os elementos
    button.click()
    if browser.is_text_present("No results for #cobrateam"):
        print "nobody likes us =("
    else:
        print "we're popular =)"

    O que eu acho mais bacana nesta ferramenta são os seletores, facilitam muito na hora de checar resultados e comportamentos.

    A comunidade em volta desta ferramenta está em constante crescimento e atividade. Portanto, caso você queira contribuir com o projeto, vá agora mesmo para o repositório no GitHub e colabore.

    nose – Caçando testes em seu projeto (Python)

    E quando queremos fugir da regra? Aposto que chegará um momento em que a estrutura de diretórios padrão, necessária para a execução dos seus testes em Django, não te satisfará mais. O que fazer neste caso? Simples, recorra ao Nose!

    O Nose estende os recursos da unittest e facilita a escrita e carregamento dos testes em projetos Python. De uma forma mais detalhada, ele percorre o seu projeto (ou uma determinada região de seu escolha) executando subclasses da unittest.TestCase ou funções que contenham “test”. Por exemplo:

    # test_subclasse.py
    import unittest
    
    class SubclasseTest(unittest.TestCase):
        def test_um_eh_verdadeiro(self):
            self.assertTrue(1)
    
    # test_funcao.py
    def test_zero_eh_falso():
        assert 0 == False

    Ao executar o comando nosetests o nose se encarregará de procurar e carregar os testes:

    $ nosetests
    ..
    ----------------------------------------------------------------------
    Ran 2 tests in 0.005s
    
    OK

    É claro que existe uma “mágica” aí. Na verdade o nose pesquisará por arquivos Python com “test” em seu nome, por funções com “test” em seu enunciado, e por classes com métodos “test” em sua declaração. Ele age mesmo como um “runner“, tendo a capacidade de lidar com testes escritos com unittest ou não.

    Essa é só a ponta do iceberg. É possível construir plugins para o nose, permitindo melhorar ainda mais o seu ambiente de testes (como por exemplo, permitir que o nose funcione em subprocess separados).

    Caçando testes em seu projeto (Django)

    Para facilitar ainda mais a escrita de testes em Django existem plugins como o django-nose, que permite que você substitua o Test Runner padrão da framework por um específico que utiliza o nose, unindo assim a facilidade e “add-ons” do nose com o ambiente de testes do Django.

    lettuceBDD em Django

    E se você estava se perguntando sobre BDD em Django, eu apresento a Lettuce!

    Esta ferramenta, baseada na Cucumber, permite com que você escreva estórias utilizando linguagem ubíqua, mais próxima da área de negócios do que da área técnica, e automatize a validação delas.

    O mais bacana é que ela já vem preparada para o Django, permitindo que a gente execute os testes de comportamento de forma fácil e rápida:

    Feature: Rocking with lettuce and django
    
        Scenario: Simple Hello World
            Given I access the url "/"
            Then I see the header "Hello World"
    
        Scenario: Hello + capitalized name
            Given I access the url "/some-name"
            Then I see the header "Hello Some Name"

    Estória escrita, vamos escrever o script Python que validará se está tudo de acordo:

    from lettuce import *
    from lxml import html
    from django.test.client import Client
    
    @before.all
    def set_browser():
        world.browser = Client()
    
    @step(r'I access the url "(.*)"')
    def access_url(step, url):
        response = world.browser.get(url)
        world.dom = html.fromstring(response.content)
    
    @step(r'I see the header "(.*)"')
    def see_header(step, text):
        header = world.dom.cssselect('h1')[0]
        assert header.text == text

    Basta executá-lo da seguinte maneira:

    $ python manage.py harvest

    Confira mais informações sobre como utilizar o lettuce com Django.

    fudge – Ajude o Python a mentir

    O Fudge é um módulo Python que auxilia na construção de objetos “dublês” (mocks e stubs), que permitem escrever testes sem necessariamente possuir um serviço ativo ou um objeto construído.

    Um caso comum: Você está construindo uma API que autentica via OAuth ao Twitter e está utilizando testes para guiar o seu desenvolvimento. Não é interessante que nossos testes sejam dependentes da disponibilidade do serviço do Twitter, portanto, escrevemos um “objeto mentiroso”, que simulará este serviço, aceitando uma entrada e gerando um saída:

    import fudge
    @fudge.patch('oauthtwitter.OAuthApi')
    def test(FakeOAuthApi):
            (FakeOAuthApi.expects_call()
                .with_args('', '',
                             '', '')
                .returns_fake()
                .expects('UpdateStatus').with_arg_count(1))
    
    post_msg_to_twitter("hey there fellow testing freaks!")

    Pronto! Sabendo que valores serão passados, e quais os resultados, podemos simular o comportamento daquele serviço. Prático, não?

    Considerações finais

    Estas são as ferramentas que eu costumo utilizar em meus projetos Python/Django. É claro que existem outras, na verdade existem várias. Tenha em mente que a ferramenta é apenas um meio de garantir, através de testes, que você está guiando a sua aplicação para o lugar certo. Os testes automatizados no final servem para garantir que ela ainda segue este caminho, que contribuições realizadas tardiamente não “quebraram” o comportamento que você escreveu no início do desenvolvimento.

    Tenho a intenção de escrever um post mais prático sobre testes e Django. Fiquem no aguardo ;)

    E você? Tem alguma ferramenta para recomendar? Utilize os comentários abaixo para compartilhá-la.

    Referências

    Até a próxima…

    Fonte: Klaus Laube



      Tecnólogo em Análise e Desenvolvimento de Sistemas pelo Centro Universitário de Jaraguá do Sul (UNERJ), Técnico em Informática com ênfase em Sistemas de Informação pelo Centro Politécnico Geraldo Werninghaus (CEPEG). Desenvolvedor Web defensor dos padrões Web. Usuário Linux, apaixonado por Python. Escreve quando pode no http://www.klauslaube.com.br.

      Deixe seu comentário

      Seu endereço de e-mail não será publicado. Campos com * são obrigatórios!

      *

      *

      Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>