TDD com Python
Siga o bode dos testes: usando Django, Selenium e JavaScript
Descrição do livro
Ao conduzir você pelo desenvolvimento de uma verdadeira aplicação web do início ao fim, a segunda edição deste guia “mão na massa” mostra as vantagens práticas do TDD (Test-Driven Development, ou Desenvolvimento Orientado a Testes) com Python. Você aprenderá a escrever e a executar testes antes de construir cada parte de sua aplicação, e então desenvolverá a quantidade mínima de código necessária para que os testes passem. O resultado? Um código limpo, que funcionará.
Durante o processo, você conhecerá o básico sobre Django, Selenium, Git, jQuery e Mock, junto com as técnicas atuais para desenvolvimento web. Se estiver pronto para levar suas habilidades com Python para o próximo patamar, este livro – atualizado com Python 3.6 – mostrará claramente como o TDD incentiva você a criar designs simples e pode lhe inspirar confiança.
mergulhe no fluxo de trabalho de TDD, incluindo o ciclo de testes de unidade/código e refatoração;
utilize testes de unidade para classes e funções, e testes funcionais para interações com usuários no navegador;
saiba quando e como usar objetos simulados e conheça os prós e contras dos testes isolados versus testes integrados;
teste e automatize suas implantações com um servidor de staging;
aplique testes nos plugins de terceiros que você integrar ao seu site;
execute testes automaticamente usando um ambiente de Integração Contínua;
utilize TDD para construir uma API REST com uma interface de frontend Ajax.
Sumário
- Elogios para TDD com Python
- Prefácio
- Pré-requisitos e suposições
- Vídeo complementar
- Agradecimentos
- Básico sobre TDD e Django
- Capítulo 1 ■ Configurando o Django com um teste funcional
- Obedeça ao Testing Goat! Não faça nada até ter um teste
- Deixando o Django pronto para funcionar
- Iniciando um repositório no Git
- Capítulo 2 ■ Estendendo nosso teste funcional usando unittest
- Usando teste funcional para definir o escopo de uma aplicação mínima viável
- Módulo unittest da biblioteca-padrão de Python
- Commit
- Capítulo 3 ■ Testando uma página inicial simples com testes de unidade
- Nossa primeira aplicação Django e nosso primeiro teste de unidade
- Testes de unidade e como eles diferem dos testes funcionais
- Testes de unidade no Django
- MVC de Django, URLs e funções de view
- Finalmente! Vamos realmente escrever um pouco de código de aplicação!
- urls py
- Fazendo testes de unidade em uma view
- O ciclo de testes de unidade/código
- Capítulo 4 ■ O que estamos fazendo com todos esses testes? (E a refatoração)
- Programar é como puxar um balde de água de um poço
- Usando o Selenium para testar interações com o usuário
- A regra “Não teste constantes’’, e os templates que vêm para nos salvar
- Refatorando de modo a usar um template
- Django Test Client
- Sobre a refatoração
- Um pouco mais sobre a nossa página inicial
- Revisão: o processo de TDD
- Capítulo 5 ■ Salvando a entrada do usuário: testando o banco de dados
- Preparando o nosso formulário para enviar uma requisição POST
- Processando uma requisição POST no servidor
- Passando variáveis Python para serem renderizadas no template
- Três acertos e refatorar
- ORM do Django e o nosso primeiro modelo
- Nossa primeira migração de banco de dados
- Os testes vão surpreendentemente longe
- Um novo campo implica uma nova migração
- Salvando o POST no banco de dados
- Redirecionar após um POST
- Renderizando itens no template
- Criando nosso banco de dados de produção com migrate
- Revisão
- Capítulo 6 ■ Melhorando os testes funcionais: garantindo o isolamento e removendo sleeps vodus
- Garantindo o isolamento dos testes em testes funcionais
- Executando somente os testes de unidade
- Informação extra: atualizando o Selenium e o Geckodriver
- Sobre esperas implícitas e explícitas, e time sleeps vodus
- Capítulo 7 ■ Trabalhando de forma incremental
- Design pequeno quando necessário
- Sem um grande design logo no início
- YAGNI!
- (No estilo) REST
- Implementando o novo design de forma incremental usando TDD
- Garantindo que teremos um teste de regressão
- Iterando em direção ao novo design
- Dando um primeiro passo autocontido: um novo URL
- Um novo URL
- Uma nova função de view
- Verde? Refatorar
- Outro pequeno passo: um template separado para visualizar listas
- Um terceiro passo pequeno: um URL para adicionar itens de lista
- Uma classe de testes para a criação de uma nova lista
- Um URL e uma view para a criação de uma nova lista
- Removendo código e testes não redundantes
- Uma regressão! Apontando nossos formulários para o novo URL
- Encarando a situação de frente: ajustando nossos modelos
- Um relacionamento de chave estrangeira
- Adaptando o restante do mundo aos novos modelos
- Cada lista deve ter o próprio URL
- Capturando parâmetros de URLs
- Adaptando new_list para o novo mundo
- Os testes funcionais detectam outra regressão
- Mais uma view para tratar a adição de itens em uma lista existente
- Tome cuidado com expressões regulares gulosas!
- Último URL novo
- Última nova view
- Testando os objetos de contexto de resposta diretamente
- Uma última refatoração usando inclusões de URL
- Sine qua nons do desenvolvimento web
- Capítulo 8 ■ Embelezamento: layout e estilização, e o que testar sobre eles
- O que testar funcionalmente quanto ao layout e ao estilo
- Embelezamento: usando um framework CSS
- Herança de templates do Django
- Integrando o Bootstrap
- Linhas e colunas
- Arquivos estáticos no Django
- Mudando para StaticLiveServerTestCase
- Usando componentes do Bootstrap para melhorar a aparência do site
- Jumbotron!
- Entradas maiores
- Estilização de tabelas
- Usando o nosso próprio CSS
- O que não havíamos revelado: collectstatic e outros diretórios estáticos
- Alguns pontos que ficaram de fora
- Capítulo 9 ■ Testando a implantação usando um site de staging
- TDD e as áreas perigosas da implantação
- Como sempre, comece com um teste
- Obtendo um nome de domínio
- Provisionamento manual de um servidor para hospedar o nosso site
- Escolhendo o lugar para hospedar o nosso site
- Iniciando um servidor
- Contas de usuário, SSH e privilégios
- Instalando o Nginx
- Instalando o Python 3.6
- Configurando domínios para o ambiente de staging e o ambiente live
- Implantando o nosso código manualmente
- Acertando a localização do banco de dados
- Criando um virtualenv manualmente e usando requirements txt
- Configuração simples do Nginx
- Criando o banco de dados com migrate
- Sucesso! Nossa implantação hack funciona
- Capítulo 10 ■ Chegando a uma implantação pronta para produção
- Passando a usar o Gunicorn
- Fazendo o Nginx servir arquivos estáticos
- Passando a usar sockets Unix
- Alterando DEBUG para false e configurando ALLOWED_HOSTS
- Usando Systemd para garantir que o Gunicorn inicie no boot
- Pensando em automatizar
- Salvando o nosso progresso
- Capítulo 11 ■ Automatizando a implantação com o Fabric
- Detalhando um script do Fabric para a nossa implantação
- Criando a estrutura de diretórios
- Obtendo nosso código-fonte com o Git
- Atualizando settings py
- Atualizando o virtualenv
- Migrando o banco de dados se for necessário
- Testando
- Implantação no ambiente live
- Configuração de Nginx e de Gunicorn usando sed
- Atribua uma tag do Git à versão
- Leituras complementares
- Comece com um FT de validação: evitando itens em branco
- Ignorando um teste
- Separando os testes funcionais em vários arquivos
- Executando um único arquivo de teste
- explícita
- Finalizando o FT
- Refatorando os testes de unidade em vários arquivos
- Capítulo 13 ■ Validação na camada do banco de dados
- Validação na camada do modelo
- Gerenciador de contexto self assertRaises
- Idiossincrasia do Django: salvar o modelo não faz a validação ser executada
- Mostrando erros de validação do modelo na view
- Verificando se uma entrada inválida não é salva no banco de dados
- renderizado
- Refatorar: transferindo a funcionalidade new_item para view_list
- Impondo a validação do modelo em view_list
- Refatorar: removendo os URLs fixos no código
- Tag de template {% url %}
- Usando get_absolute_url para redirecionamentos
- Capítulo 14 ■ Um formulário simples
- Passando a lógica de validação para um formulário
- Explorando a API dos formulários com um teste de unidade
- Passando para um ModelForm do Django
- Testando e personalizando a validação de formulário
- Usando o formulário em nossas views
- Usando o formulário em uma view com uma requisição GET
- Uma grande operação de localizar e substituir
- Usando o formulário em uma view que aceita requisições POST
- Adaptando os testes de unidade para a view new_list
- Usando o formulário na view
- Usando o formulário para exibir erros no template
- Usando o formulário na outra view
- Um método auxiliar para vários testes pequenos
- Um benefício inesperado: validação gratuita no lado cliente pelo HTML5
- Um tapinha nas costas
- No entanto, desperdiçamos muito tempo?
- Usando o método do próprio formulário para salvar dados
- Capítulo 15 ■ Formulários mais sofisticados
- Outro FT para itens duplicados
- Evitando duplicações na camada do modelo
- Reescrevendo o teste antigo do modelo
- Alguns erros de integridade aparecem quando salvamos os dados
- Fazendo experimentos com validação de itens duplicados na camada de views
- Um formulário mais complexo para tratar a validação de unicidade
- Usando o formulário de item de lista existente na view de lista
- Conclusão: o que aprendemos sobre testar o Django
- Capítulo 16 ■ Mergulhando os pés, cautelosamente, no JavaScript
- Começando com um FT
- Configurando um executor de testes básico de JavaScript
- Usando a jQuery e a div de fixture
- Construindo um teste de unidade de JavaScript para a funcionalidade desejada
- console log para prints de depuração
- Boilerplate para onload e namespacing
- Testes de JavaScript no ciclo de TDD
- Alguns tópicos que não puderam ser abordados
- Capítulo 17 ■ Implantando o nosso novo código
- Implantação no servidor de staging
- Implantação no servidor live
- O que fazer se você vir um erro de banco de dados
- Conclusão: atribua uma tag no git para a nova versão
- Tópicos mais avançados sobre testes
- Capítulo 18 ■ Autenticação de usuário, spiking e de-spiking
- Autenticação sem senha
- Programação exploratória, também conhecida como “spiking”
- Iniciando um branch para o spike
- UI de login no frontend
- Enviando emails a partir do Django
- Usando variáveis de ambiente para evitar segredos no código-fonte
- Armazenando tokens no banco de dados
- Modelos personalizados para autenticação
- Finalizando a autenticação personalizada do Django
- De-spiking
- Revertendo o nosso código de spiking
- Um modelo de usuário personalizado mínimo
- Testes como documentação
- Um modelo de token para associar emails a um ID único
- Capítulo 19 ■ Usando mocks para testar dependências externas ou reduzir a duplicação
- Antes de começar: definindo a infraestrutura básica
- Fazendo uma simulação manual, também conhecida como monkeypatching
- Biblioteca Mock de Python
- Usando unittest patch
- Avançando um pouco mais no FT
- Testando o framework de mensagens do Django
- Adicionando mensagens em nosso HTML
- Começando pelo URL de login
- Verificando se enviamos um link com um token para o usuário
- De-spiking de nosso backend personalizado de autenticação
- Um if = mais um teste
- Método get_user
- Usando o nosso backend de autenticação na view de login
- Uma razão alternativa para usar mocks: reduzir a duplicação
- Usando mock return_value
- Patching no nível de classe
- Hora da verdade: o FT passará?
- Teoricamente o FT funciona! Ele funciona na prática?
- Terminando o nosso FT, testando o logout
- Capítulo 20 ■ Fixtures de teste e um decorador para esperas explícitas
- Pulando o processo de login e criando previamente uma sessão
- Verificando se o código funciona
- Nossa função auxiliar final de espera explícita: um decorador wait
- Capítulo 21 ■ Depuração no lado do servidor
- Prova definitiva: usando o servidor de staging para capturar os últimos bugs
- Configurando o logging
- Definindo variáveis de ambiente secretas no servidor
- Adaptando o nosso FT para que possamos testar emails de verdade via POP3
- Administrando o banco de dados de testes no ambiente de staging
- Um comando de gerenciamento do Django para criar sessões
- Fazendo o FT executar o comando de gerenciamento no servidor
- Usando o Fabric diretamente de Python
- Revisão: criando sessões localmente versus no ambiente de staging
- Incluindo o nosso código de logging
- Conclusão
- Capítulo 22 ■ Finalizando “My Lists”: TDD Outside-In
- A alternativa: “Inside-Out”
- Por que dar preferência para a abordagem “Outside-In”?
- FT para “My Lists”
- Camada mais externa: apresentação e templates
- Descendo uma camada, em direção às funções de view (o controlador)
- Outro teste que passa usando a abordagem Outside-In
- Uma reestruturação rápida da hierarquia de herança dos templates
- Fazendo o design de nossa API usando o template
- Descendo para a próxima camada: o que a view passa para o template
- Descendo para a camada de modelo
- Último passo: passando dados pela API .name do template
- Capítulo 23 ■ Isolamento de testes e “Ouvindo os seus testes”
- escrito para modelos
- Primeira tentativa de usar mocks para isolamento
- Usando side_effects de mocks para verificar a sequência de eventos
- Ouça os seus testes: testes feios sinalizam a necessidade de refatorar
- Reescrevendo nossos testes para a view de modo totalmente isolado
- Uma nova suíte de testes com total isolamento
- Pensando em termos de colaboradores
- Descendo para a camada de formulários
- Finalmente descendo para a camada de modelos
- De volta às views
- A hora da verdade (e os riscos da simulação)
- Pensando nas interações entre as camadas como sendo “contratos”
- Identificando contratos implícitos
- Corrigindo o que deixamos passar
- Mais um teste
- Organizando o código: o que deve ser mantido em nossa suíte de testes integrados
- Removendo código redundante da camada de formulários
- Removendo a antiga implementação da view
- Removendo código redundante da camada de formulários
- Conclusões: quando escrever testes isolados versus testes integrados
- Deixe que a complexidade seja o seu guia
- Você deve ter ambos?
- Em frente!
- Capítulo 24 ■ Integração Contínua (CI)
- Instalando o Jenkins
- Configurando o Jenkins
- Desbloqueio inicial
- Plugins sugeridos, por enquanto
- Configurando o usuário administrador
- Adicionando plugins
- Informando ao Jenkins o local para encontrar o Python 3 e o Xvfb
- Concluindo com HTTPS
- Configurando o nosso projeto
- Primeira construção!
- Capturando imagens de tela
- Na dúvida, tente aumentar o timeout!
- Executando nossos testes de JavaScript com QUnit no Jenkins com o PhantomJS
- Instalando o node
- Acrescentando os passos de construção no Jenkins
- Outras tarefas que um servidor de CI pode fazer
- Capítulo 25 ■ Aspecto social, padrão Page e exercício para o leitor
- Um FT com vários usuários, e a função addCleanup
- Padrão Page
- Estendendo o FT para um segundo usuário, e a página “My Lists”
- Um exercício para o leitor
- Capítulo 26 ■ Testes rápidos, testes lentos e Lava Quente
- Tese: testes de unidade são super-rápidos e bons, além de tudo
- Testes mais rápidos significam desenvolvimento mais rápido
- O sagrado estado de fluxo
- sar do tempo
- Não sou eu quem está falando
- E os testes de unidade levam a um bom design
- Os problemas com os testes de unidade “puros”
- Testes isolados podem ser mais difíceis de ler e de escrever
- Testes isolados não testam automaticamente a integração
- Testes de unidade raramente capturam bugs inesperados
- Entretanto todos os problemas podem ser superados
- Síntese: afinal de contas, o que queremos de nossos testes?
- Aplicação correta
- Código limpo, possível de manter
- Fluxo de trabalho produtivo
- Soluções arquitetônicas
- Portas e adaptadores/arquitetura hexagonal/limpa
- Functional Core, Imperative Shell
- Conclusão
- Leituras complementares
- Epílogo ■ Obedeça ao Testing Goat!
- Testar é difícil
- Mantenha suas construções no CI com sinal verde
- Tenha orgulho de seus testes, assim como você tem de seu código
- Lembre-se de dar gorjetas para o pessoal do bar
- Não seja um desconhecido!
- Apêndice A ■ PythonAnywhere
- Apêndice B ■ Views baseadas em classe do Django
- Apêndice C ■ Provisionamento com o Ansible
- Apêndice D ■ Testando migrações de banco de dados
- Apêndice E ■ Desenvolvimento orientado a comportamento (BDD)
- Apêndice F ■ Construindo uma API REST: JSON, Ajax e simulação com JavaScript
- Apêndice G ■ Django-Rest-Framework
- Apêndice H ■ Folha de cola
- Apêndice I ■ O que fazer em seguida
- Apêndice J ■ Código-fonte dos exemplos
- Bibliografia
Sobre o autor
Após uma infância idílica brincando com BASIC em computadores franceses de 8 bits como o Thomson T-07, cujas teclas faziam “blip” quando pressionadas, Harry passou alguns anos profundamente infeliz dando consultoria em economia e administração. Logo redescobriu sua verdadeira natureza geek e teve sorte o bastante para acabar com um grupo de… Ver perfil completo ▶
Livros relacionados
Recursos
Opinião dos leitores
Larisse R de S
Maravilhoso!
Samuel B C da S
Excelente material! Explicação simples e bem didática!
Rodrigo C M
Ótimo livro, ótima didática.
William P de P
Ótimo livro, muito bem explicado e com conceitos explicados de forma prática.






