SlideShare uma empresa Scribd logo
1
Testes com Python:
Como fazer uma refatoração segura
2
Sobre o apresentador
Valberto Vieira Carneiro
Analista de Tecnologia da Informação - IFPB
Especialista em Qualidade e Testes de Software
3
Roteiro
1. Estudo de caso
2. Motivação
3. Por onde começar?
4. Conceitos
5. Testes
6. Refatoração
7. Dicas
4
Estudo de caso
Módulo de diárias e passagens do Instituto Federal da
Paraíba
5
Fluxo para solicitar diárias e passagens
6
Fluxo para prestar contas da viagem realizada
7
Meu Objetivo
Aplicar melhorias em um sistema que
já está em produção.
Situação
Possui uma lista com novos requisitos
Não possui nenhum teste
Possui manual de usuário
8
Sentimentos
Vamos arrumar a casa
Preciso entender
como esse código
funciona
Será que vai dar
certo?
9
Motivação
Vamos deixar os testes para depois!
Não temos tempo!
Na minha máquina funciona!
10
Testar e refatorar, como fazer?
O que testar e o que não testar?
Qual tipo de testes usar?
11
Por onde começar?
Tenha um objetivo bem definido
Verifique se o módulo possui documentação
Faça um teste exploratório nas principais funcionalidades
Estude sobre refatoração
12
Testar
13
O que é teste de software?
Os testes são realizados com a intenção de descobrir defeitos
em um sistema. [Myres, 2004]
Os testes de software podem ser usados para mostrar a
presença de defeitos, mas nunca para mostrar a ausência
deles. [Dijkstra, 1972]
14
Caixa branca
Código fonte
Testes unitários
Caixa preta
Requisitos
Testes funcionais
Tipos de testes
15
Práticas que poderiam ajudar?
Fonte: http://www.aniche.com.br/tdd/
TDD -
Test Driven Development
- Escrever o teste antes de
codificar
16
Requisitos -
Regras de negócio -
Segurança -
Permissões de usuários -
- Framework
- Métodos nativos
- Requisitos com baixo valor
de negócio**
O que testar e o que não testar?
17
Dicas
- Comece pelo mais simples!
- Evolua os testes gradativamente
- As vezes será necessário reorganizar os testes
- Teste o fluxo principal
- Teste a(s) funcionalidade(s) mais importante(s)
18
Exemplos: teste funcional básico
from django.test import TestCase
class HomologadorTestCase(TestCase):
def test_pagina_inicial(self):
response = self.client.get('/')
self.assertEqual(response.status_code, 200)
self.assertContains(response, u"Título da página")
$ ./manage.py test expedicao
19
Exemplos: afirmações
- assertEqual(a, b) # a == b
- assertNotEqual(a, b) # a <> b
- assertTrue(bool) # True
- assertFalse(bool) # False
- assertRaises(Exception) # raise Exception
- assertIn(a, b) # a in b
- assertNotIn(a, b) # a not in b
- assertGreater(a, b) # a > b
- assertLess(a, b) # a < b
20
Exemplos: teste no Suap
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def test_pode_ver_aba_homologador(self):
self.logout()
successful = self.client.login(username=self.user.username, password='123')
self.assertEqual(successful, True)
url = "/admin/expedicao/viagemservidor/"
response = self.client.get(url, follow=True)
self.assertContains(response, u"tab_viagens_homologar")
21
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def test_pode_ver_aba_homologador(self):
self.logout()
successful = self.client.login(username=self.user.username, password='123')
self.assertEqual(successful, True)
url = "/admin/expedicao/viagemservidor/"
response = self.client.get(url, follow=True)
self.assertContains(response, u"tab_viagens_homologar")
Exemplos: teste no Suap
22
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def acessar_como(self, user):
self.logout()
successful = self.client.login(username=user.username, password='123')
self.assertEqual(successful, True)
def test_pode_ver_aba_homologador(self):
self.acessar_como(self.homologador)
url = "/admin/expedicao/viagemservidor/"
response = self.client.get(url, follow=True)
self.assertContains(response, u"tab_viagens_homologar")
Exemplos: teste no Suap
23
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def acessar_como(self, user):
self.logout()
successful = self.client.login(username=user.username, password='123')
self.assertEqual(successful, True)
def test_pode_ver_aba_homologador(self):
self.acessar_como(self.homologador)
url = "/admin/expedicao/viagemservidor/"
response = self.client.get(url, follow=True)
self.assertContains(response, u"tab_viagens_homologar")
Exemplos: teste no Suap
24
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def acessar_como(self, user):
def test_pode_ver_aba_homologador(self):
self.acessar_como(self.homologador)
url = "/admin/expedicao/viagemservidor/"
response = self.client.get(url, follow=True)
self.assertContains(response, u"tab_viagens_homologar")
Exemplos: teste no Suap
25
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def acessar_como(self, user):
def test_pode_ver_aba_homologador(self):
self.acessar_como(self.homologador)
url = "/admin/expedicao/viagemservidor/"
response = self.client.get(url, follow=True)
self.assertContains(response, u"tab_viagens_homologar")
Exemplos: teste no SuapChangelist {{ app_label }}_{{ model_name }}_changelist
Add {{ app_label }}_{{ model_name }}_add /add
History {{ app_label }}_{{ model_name }}_history /id/history
Delete {{ app_label }}_{{ model_name }}_delete /id/delete
Change {{ app_label }}_{{ model_name }}_change /id
'expedicao_viagemservidor_changelist'
'/admin/expedicao/viagemservidor/'
26
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def acessar_como(self, user):
def get_changelist_page(cls):
...
def test_pode_ver_aba_homologador(self):
self.acessar_como(self.homologador)
response = self.get_changelist_page(models.ViagemServidor)
self.assertContains(response, u"tab_viagens_homologar")
Exemplos: teste no Suap
27
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def acessar_como(self, user):
def get_changelist_page(cls):
def test_pode_ver_aba_homologador(self):
self.acessar_como(self.homologador)
response = self.get_changelist_page(models.ViagemServidor)
self.assertContains(response, u"tab_viagens_homologar")
Exemplos: teste no Suap
28
from django.test import TestCase
class SuapTestCase(TestCase):
class ExpedicaoTestCase(SuapTestCase):
class HomologadorTestCase(ExpedicaoTestCase):
def acessar_como(self, user):
def get_changelist_page(cls):
def test_pode_ver_aba_homologador(self):
self.acessar_como(self.homologador)
response = self.get_changelist_page(models.ViagemServidor)
self.assertContains(response, u"tab_viagens_homologar")
# self.logout()
# successful = self.client.login(username=self.user.username, password='123')
# self.assertEqual(successful, True)
# url = "/admin/expedicao/viagemservidor/"
# response = self.client.post(url, follow=True)
# self.assertContains(response, u"tab_viagens_homologar")
Exemplos: teste no Suap
29
Refatorar
30
Refatorar é…
um processo disciplinado de alterar o código de um
sistema sem alterar o seu comportamento observável
buscando melhorar a estrutura interna e minimizando a
chance de introdução de novas falhas.
(Martin Fowler, Kent Beck)
Exige experiência e envolve uma grande
responsabilidade.
31
Refatorar não é…
Alterar o código adicionando novos recursos
Reescrever ou substituir grande partes do código
32
Etapas
1. Detecção de oportunidades de refactoring
2. Decisão do Uso (custos e benefícios)
3. Preparação da avaliação
4. Execução de um dado refactoring
5. Avaliação
33
Etapa 1: Detecção de oportunidades de refactoring
Code smell
é como se aquele trecho de código cheirasse e você sabe
que precisa ser refatorado
Problemas mais comuns
código duplicado | método longo | classes grandes
comandos switch | campo temporário
classe ociosa | comentários
pylint
34
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Comentário longo.
- Comentário desnecessário.
- Comentário não condiz com o objetivo do método.
- Imports não utilizados.
- Método/código duplicado comum.utils.get_funcionario.
- Linhas com mais de 80 caracteres.
- Método muito extenso.
- Número mágico.
- Nome muito grande para uma variável (23 caracteres).
35
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Comentário longo.
- Comentário desnecessário.
- Comentário não condiz com o objetivo do método.
- Imports não utilizados.
- Método/código duplicado comum.utils.get_funcionario.
- Linhas com mais de 80 caracteres.
- Método muito extenso.
- Número mágico.
- Nome muito grande para uma variável (23 caracteres).
# Cria o relatório referente a esta viagem
relatorio = RelatorioViagem(viagem=viagem)
relatorio.save()
36
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Comentário longo.
- Comentário desnecessário.
- Comentário não condiz com o objetivo do método.
- Imports não utilizados.
- Método/código duplicado comum.utils.get_funcionario.
- Linhas com mais de 80 caracteres.
- Método muito extenso.
- Número mágico.
- Nome muito grande para uma variável (23 caracteres).
if (data.isoweekday() >= 6):
37
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Comentário longo.
- Comentário desnecessário.
- Comentário não condiz com o objetivo do método.
- Imports não utilizados.
- Método/código duplicado comum.utils.get_funcionario.
- Linhas com mais de 80 caracteres.
- Método muito extenso.
- Número mágico.
- Nome muito grande para uma variável (23 caracteres).
SABADO, DOMINGO = 6, 7
if data.isoweekday() in [SABADO, DOMINGO]:
38
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Aquivo não tem limitador de extensão nem de tamanho.
- Extrair consulta para um método.
- Nomenclatura não exite mais.
- Condições complexas demais. Substituir por método:
is_empty(nome_campo).
- Substituir condições negativas por uma afirmativas.
39
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Aquivo não tem limitador de extensão nem de tamanho.
- Extrair consulta para um método.
- Nomenclatura não exite mais.
- Condições complexas demais. Substituir por método:
is_empty(nome_campo).
- Substituir condições negativas por uma afirmativas.
arquivo = models.FileField(
upload_to='/comprovantes/',
verbose_name=u'Comprovante')
40
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Aquivo não tem limitador de extensão nem de tamanho.
- Extrair consulta para um método.
- Nomenclatura não exite mais.
- Condições complexas demais. Substituir por método:
is_empty(nome_campo).
- Substituir condições negativas por uma afirmativas.
arquivo = models.FileField(
upload_to='/comprovantes/',
verbose_name=u'Comprovante',
help_text=u'Tamanho máximo 2MB.',
validators=[FileValidator()])
41
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Aquivo não tem limitador de extensão nem de tamanho.
- Extrair consulta para um método.
- Nomenclatura não exite mais.
- Condições complexas demais. Substituir por método:
is_empty(nome_campo).
- Substituir condições negativas por uma afirmativas.
historico = HistoricoSolicitacao.objects.
filter(viagem=self).
order_by('-data').
all()[0]
historico = self.historicos.latest('data')
42
Exemplos: detecção dos pontos de melhoria
# TODO refactory:
- Aquivo não tem limitador de extensão nem de tamanho.
- Extrair consulta para um método.
- Nomenclatura não exite mais.
- Condições complexas demais. Substituir por método:
is_empty(nome_campo).
- Substituir condições negativas por uma afirmativas.
def ultimo_historico():
return self.historicos.latest('data')
historico = ultimo_historico()
43
Etapa 2: Decisão do Uso (custos e benefícios)
Custos e benefícios
Tempo e esforço necessários valerão a pena?
Decisão não automatizada
Código duplicado:
Extrair Método, Extrair Classe, Subir Método na
Hierarquia ou Substituir Algoritmo
44
Etapa 3: Preparação da avaliação
Desenvolver testes
Garantir que o comportamento do sistema seja mantido
Decidir qual tipo de testes
Testes funcionais
Caixa preta
45
Dicas
Crie grupos de funções que deseja testar
- perfil de usuário (testar acesso e negação de acesso)
- fluxo de negócio
- regras de negócio (validações)
46
Exemplos: Preparação da avaliação
class ExpedicaoTestCase(SuapTestCase):
Testes Tempo
class AdministradorTestCase(ExpedicaoTestCase): | 4 | 00:00:38 |
class ExecutorTestCase(ExpedicaoTestCase): | 4 | 00:00:02 |
class HomologadorTestCase(ExpedicaoTestCase): | 1 | 00:00:00 |
class AutorizadorUOTestCase(ExpedicaoTestCase): | 2 | 00:00:01 |
class ChefeTestCase(ExpedicaoTestCase): | 5 | 00:00:03 |
class SubstitutoTestCase(ExpedicaoTestCase): | 4 | 00:00:03 |
class ViagemServidorTestCase(ExpedicaoTestCase): | 14 | 00:00:11 |
class RelatorioViagemTestCase(ExpedicaoTestCase):| 7 | 00:00:09 |
TOTAL: 41 | 00:01:12 |
Cobertura 72%
$ pip install coverage
47
Etapa 4: Execução de um dado refactoring
Aplicar as refatorações
Objetivo é eliminar o code smell
Qual o momento certo?
Atividade contínua, integrada ao desenvolvimento:
- Acrescentar uma função
- Consertar uma falha
- Revisar o código
48
Exemplos: Aplicar refatorações
def relatorio_detail(request, id):
title = u'Relatório do Servidor'
usuario = request.user
try:
relatorio = RelatorioViagem.objects.get(id=id)
except RelatorioViagem.DoesNotExist:
return HttpResponseBadRequest(u'O relatório não existe!')
if not (eh_dono_viagem(request, relatorio.viagem.id) or 
eh_ordenador(request) or 
eh_executor(request) or 
usuario.eh_chefe_do_setor(usuario.setor)):
raise PermissionDenied
return locals()
49
Exemplos: Aplicar refatorações
def relatorio_detail(request, id):
title = u'Relatório do Servidor'
usuario = request.user
try:
relatorio = RelatorioViagem.objects.get(id=id)
except RelatorioViagem.DoesNotExist:
return HttpResponseBadRequest(u'O relatório não existe!')
if not (eh_dono_viagem(request, relatorio.viagem.id) or 
eh_ordenador(request) or 
eh_executor(request) or 
usuario.eh_chefe_do_setor(usuario.servidor.setor)):
raise PermissionDenied
return locals()
relatorio = get_object_or_404(RelatorioViagem, pk=id)
50
Exemplos: Aplicar refatorações
def relatorio_detail(request, id):
title = u'Relatório do Servidor'
usuario = request.user
relatorio = get_object_or_404(RelatorioViagem, pk=id)
if not (eh_dono_viagem(request, relatorio.viagem.id) or 
eh_ordenador(request) or 
eh_executor(request) or 
usuario.eh_chefe_do_setor(usuario.setor)):
raise PermissionDenied
return locals()
51
Exemplos: Aplicar refatorações
def relatorio_detail(request, id):
title = u'Relatório do Servidor'
usuario = request.user
relatorio = get_object_or_404(RelatorioViagem, pk=id)
if not (eh_dono_viagem(request, relatorio.viagem.id) or 
eh_ordenador(request) or 
eh_executor(request) or 
usuario.eh_chefe_do_setor(usuario.setor)):
raise PermissionDenied
return locals()
regra = regras.RelatorioViagemRegras(relatorio)
if not regra.pode_ver(request.user):
raise PermissionDenied
52
Exemplos: Aplicar refatorações
def relatorio_detail(request, id):
title = u'Relatório do Servidor'
relatorio = get_object_or_404(RelatorioViagem, pk=id)
regra = regras.RelatorioViagemRegras(relatorio)
if not regra.pode_ver(request.user):
raise PermissionDenied
return locals()
Etapa 5: Avaliação
O comportamento é o mesmo?
Analisar resultado dos testes
Realizar análise cognitiva
Buscar novo code smell
53
54
Fonte: CARNEIRO, 2003
55
Perguntas
56
Referências
- CARNEIRO, Glauco de F. Usando medição de código fonte para refactoring. Abril de 2003. 123 p. Dissertação (Mestrado
Profissional em Redes de Computadores) - Universidade Salvador, Salvador, 2003.
- Dijkstra, E. W. "The Humble Programmer". Communications of the ACM 15 (10): 859–866, 1972.
- Entendendo Testes de Software https://willianjusten.com.br/entendendo-testes-de-software/
- FOWLER, Martin et al. Refatoração: Aperfeiçoando o Projeto de Código Existente. trad.Acauan Fernandes – Porto Alegre:
Bookman, 2004.
- Improve Your Python: Understanding Unit Testing https://jeffknupp.com/blog/
- List for code-quality tools related to Python https://mail.python.org/mailman/listinfo/code-quality
- Myres , G. F. “The Art of Software Testing”. Ed. John Wiley & Sons, Inc. New Jersey, 2004.
- O que é e o que não é refatoração – de acordo com Kent Beck e Martin Fowler
https://dzone.com/articles/what-refactoring-and-what-it-0
- Os 10 princípios dos Testes de Software http://gtsw.blogspot.com.br/2007/12/os-princpios-dos-testes-de-software.html
- Refactoring Patterns https://dzone.com/refcardz/refactoring-patterns
- Review of Python Static Analysis Tools http://blog.codacy.com/2016/01/08/review-of-python-static-analysis-tools/
- Start Here: Introductions to Python Testing Frameworks http://pythontesting.net/start-here/
- Testes e Refatoração http://pt.slideshare.net/jeveaux/testes-e-refatorao-presentation-622966
- Writing unit tests in Python: How do I start?
http://stackoverflow.com/questions/3371255/writing-unit-tests-in-python-how-do-i-start

Mais conteúdo relacionado

Mais procurados

Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
Fabio Collini
 
Fundamentos de Padrões de Projeto de Software
Fundamentos de Padrões de Projeto de SoftwareFundamentos de Padrões de Projeto de Software
Fundamentos de Padrões de Projeto de Software
Álvaro Farias Pinheiro
 
Estrutura de Dados Apoio (Tabela Hash)
Estrutura de Dados Apoio (Tabela Hash)Estrutura de Dados Apoio (Tabela Hash)
Estrutura de Dados Apoio (Tabela Hash)
Leinylson Fontinele
 
Testes em métodos ágeis
Testes em métodos ágeisTestes em métodos ágeis
Testes em métodos ágeis
Qualister
 
Tabela Hash
Tabela HashTabela Hash
Tabela Hash
Marcos Castro
 
Ponteiros e Alocação Dinâmica
Ponteiros e Alocação DinâmicaPonteiros e Alocação Dinâmica
Ponteiros e Alocação Dinâmica
Eduardo Oliveira
 
Introdução ao desenvolvimento da web.pptx
Introdução ao desenvolvimento da web.pptxIntrodução ao desenvolvimento da web.pptx
Introdução ao desenvolvimento da web.pptx
MarceloRosenbrock1
 
Java: Collections
Java: CollectionsJava: Collections
Java: Collections
Arthur Emanuel
 
Desenvolvimento Web com Java Script Full Stack
Desenvolvimento Web com Java Script Full StackDesenvolvimento Web com Java Script Full Stack
Desenvolvimento Web com Java Script Full Stack
Erick Petrucelli
 
Linguagem C - Ponteiros
Linguagem C - PonteirosLinguagem C - Ponteiros
Linguagem C - Ponteiros
Elaine Cecília Gatto
 
Java Coleções
Java ColeçõesJava Coleções
Java Coleções
Mario Jorge Pereira
 
Engenharia de Requisitos
Engenharia de RequisitosEngenharia de Requisitos
Engenharia de Requisitos
Cloves da Rocha
 
Recursividade
RecursividadeRecursividade
Recursividade
Sérgio Souza Costa
 
Curso de Java (Parte 3)
 Curso de Java (Parte 3) Curso de Java (Parte 3)
Curso de Java (Parte 3)
Mario Sergio
 
Diagrama de Perfil e Estruturas Compostas
Diagrama de Perfil e Estruturas CompostasDiagrama de Perfil e Estruturas Compostas
Diagrama de Perfil e Estruturas Compostas
OctviodeOliveiraJorg
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao java
Armando Daniel
 
Introdução a estruturas de dados em python
Introdução a estruturas de dados em pythonIntrodução a estruturas de dados em python
Introdução a estruturas de dados em python
Alvaro Oliveira
 
Comparação Sintaxe Portugol vs Java
Comparação Sintaxe Portugol vs JavaComparação Sintaxe Portugol vs Java
Comparação Sintaxe Portugol vs Java
Mario Sergio
 
Algoritmos e lp parte3-pseudocódigo
Algoritmos e lp parte3-pseudocódigoAlgoritmos e lp parte3-pseudocódigo
Algoritmos e lp parte3-pseudocódigo
Mauro Pereira
 
Lógica de Programação
Lógica de ProgramaçãoLógica de Programação
Lógica de Programação
Adao Chiavelli
 

Mais procurados (20)

Kotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere StockholmKotlin delegates in practice - Kotlin Everywhere Stockholm
Kotlin delegates in practice - Kotlin Everywhere Stockholm
 
Fundamentos de Padrões de Projeto de Software
Fundamentos de Padrões de Projeto de SoftwareFundamentos de Padrões de Projeto de Software
Fundamentos de Padrões de Projeto de Software
 
Estrutura de Dados Apoio (Tabela Hash)
Estrutura de Dados Apoio (Tabela Hash)Estrutura de Dados Apoio (Tabela Hash)
Estrutura de Dados Apoio (Tabela Hash)
 
Testes em métodos ágeis
Testes em métodos ágeisTestes em métodos ágeis
Testes em métodos ágeis
 
Tabela Hash
Tabela HashTabela Hash
Tabela Hash
 
Ponteiros e Alocação Dinâmica
Ponteiros e Alocação DinâmicaPonteiros e Alocação Dinâmica
Ponteiros e Alocação Dinâmica
 
Introdução ao desenvolvimento da web.pptx
Introdução ao desenvolvimento da web.pptxIntrodução ao desenvolvimento da web.pptx
Introdução ao desenvolvimento da web.pptx
 
Java: Collections
Java: CollectionsJava: Collections
Java: Collections
 
Desenvolvimento Web com Java Script Full Stack
Desenvolvimento Web com Java Script Full StackDesenvolvimento Web com Java Script Full Stack
Desenvolvimento Web com Java Script Full Stack
 
Linguagem C - Ponteiros
Linguagem C - PonteirosLinguagem C - Ponteiros
Linguagem C - Ponteiros
 
Java Coleções
Java ColeçõesJava Coleções
Java Coleções
 
Engenharia de Requisitos
Engenharia de RequisitosEngenharia de Requisitos
Engenharia de Requisitos
 
Recursividade
RecursividadeRecursividade
Recursividade
 
Curso de Java (Parte 3)
 Curso de Java (Parte 3) Curso de Java (Parte 3)
Curso de Java (Parte 3)
 
Diagrama de Perfil e Estruturas Compostas
Diagrama de Perfil e Estruturas CompostasDiagrama de Perfil e Estruturas Compostas
Diagrama de Perfil e Estruturas Compostas
 
Java introdução ao java
Java   introdução ao javaJava   introdução ao java
Java introdução ao java
 
Introdução a estruturas de dados em python
Introdução a estruturas de dados em pythonIntrodução a estruturas de dados em python
Introdução a estruturas de dados em python
 
Comparação Sintaxe Portugol vs Java
Comparação Sintaxe Portugol vs JavaComparação Sintaxe Portugol vs Java
Comparação Sintaxe Portugol vs Java
 
Algoritmos e lp parte3-pseudocódigo
Algoritmos e lp parte3-pseudocódigoAlgoritmos e lp parte3-pseudocódigo
Algoritmos e lp parte3-pseudocódigo
 
Lógica de Programação
Lógica de ProgramaçãoLógica de Programação
Lógica de Programação
 

Destaque

Refatoração de código Python
Refatoração de código PythonRefatoração de código Python
Refatoração de código Python
diogobaeder
 
Introcucao aos Sistemas Distribuidos
Introcucao aos Sistemas DistribuidosIntrocucao aos Sistemas Distribuidos
Introcucao aos Sistemas Distribuidos
Valberto Carneiro
 
Resume
ResumeResume
10 facts about the adult bullying mindset
10 facts about the adult bullying mindset10 facts about the adult bullying mindset
10 facts about the adult bullying mindset
Nathan Segal
 
PORTFOLIO Ángela Tomás Olmos EN
PORTFOLIO Ángela Tomás Olmos ENPORTFOLIO Ángela Tomás Olmos EN
PORTFOLIO Ángela Tomás Olmos EN
Ángela Tomás Olmos
 
Curriculum vitae gm
Curriculum vitae gmCurriculum vitae gm
Curriculum vitae gm
Gamal Al-Maghraby
 
VanderVeen Resume
VanderVeen ResumeVanderVeen Resume
VanderVeen Resume
Ashley Vander Veen
 
Sistemas operacionais sistemas-distribuidos
Sistemas operacionais sistemas-distribuidosSistemas operacionais sistemas-distribuidos
Sistemas operacionais sistemas-distribuidos
robsons75
 
Question 1 media coursework
Question 1 media courseworkQuestion 1 media coursework
Question 1 media coursework
Alexandra Offer
 
Aula 2 introdução a sistemas distribuídos
Aula 2   introdução a sistemas distribuídosAula 2   introdução a sistemas distribuídos
Aula 2 introdução a sistemas distribuídos
Eduardo de Lucena Falcão
 
Introdução aos Sistemas Distribuídos
Introdução aos Sistemas DistribuídosIntrodução aos Sistemas Distribuídos
Introdução aos Sistemas Distribuídos
Frederico Madeira
 
Presentacion geografia
Presentacion geografiaPresentacion geografia
Presentacion geografia
SuperWow121
 
4.2.1 resrva hotelera
4.2.1 resrva hotelera4.2.1 resrva hotelera
4.2.1 resrva hotelera
vivekely
 

Destaque (13)

Refatoração de código Python
Refatoração de código PythonRefatoração de código Python
Refatoração de código Python
 
Introcucao aos Sistemas Distribuidos
Introcucao aos Sistemas DistribuidosIntrocucao aos Sistemas Distribuidos
Introcucao aos Sistemas Distribuidos
 
Resume
ResumeResume
Resume
 
10 facts about the adult bullying mindset
10 facts about the adult bullying mindset10 facts about the adult bullying mindset
10 facts about the adult bullying mindset
 
PORTFOLIO Ángela Tomás Olmos EN
PORTFOLIO Ángela Tomás Olmos ENPORTFOLIO Ángela Tomás Olmos EN
PORTFOLIO Ángela Tomás Olmos EN
 
Curriculum vitae gm
Curriculum vitae gmCurriculum vitae gm
Curriculum vitae gm
 
VanderVeen Resume
VanderVeen ResumeVanderVeen Resume
VanderVeen Resume
 
Sistemas operacionais sistemas-distribuidos
Sistemas operacionais sistemas-distribuidosSistemas operacionais sistemas-distribuidos
Sistemas operacionais sistemas-distribuidos
 
Question 1 media coursework
Question 1 media courseworkQuestion 1 media coursework
Question 1 media coursework
 
Aula 2 introdução a sistemas distribuídos
Aula 2   introdução a sistemas distribuídosAula 2   introdução a sistemas distribuídos
Aula 2 introdução a sistemas distribuídos
 
Introdução aos Sistemas Distribuídos
Introdução aos Sistemas DistribuídosIntrodução aos Sistemas Distribuídos
Introdução aos Sistemas Distribuídos
 
Presentacion geografia
Presentacion geografiaPresentacion geografia
Presentacion geografia
 
4.2.1 resrva hotelera
4.2.1 resrva hotelera4.2.1 resrva hotelera
4.2.1 resrva hotelera
 

Semelhante a Testes com python: como fazer uma refatoração segura

Ctai Teste De Software Aula 1
Ctai Teste De Software Aula 1Ctai Teste De Software Aula 1
Ctai Teste De Software Aula 1
Victor Hugo Germano
 
PHPUnit e teste de software
PHPUnit e teste de softwarePHPUnit e teste de software
PHPUnit e teste de software
ricardophp
 
Testando Aplicações Django: Quando, Como e Onde?
Testando Aplicações Django: Quando, Como e Onde?Testando Aplicações Django: Quando, Como e Onde?
Testando Aplicações Django: Quando, Como e Onde?
Bernardo Fontes
 
Ganhando tempo com casos de testes
Ganhando tempo com casos de testesGanhando tempo com casos de testes
Ganhando tempo com casos de testes
Michael Castillo Granados
 
Atividades de Teste e Cobertura de Código em Java
Atividades de Teste e Cobertura de Código em JavaAtividades de Teste e Cobertura de Código em Java
Atividades de Teste e Cobertura de Código em Java
aceiro
 
Introdução ao design de teste de software
Introdução ao design de teste de softwareIntrodução ao design de teste de software
Introdução ao design de teste de software
Kleitor Franklint Correa Araujo
 
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Claudinei Brito Junior
 
1 2 3 - Testando - Automatizando os testes de software
1 2 3 - Testando - Automatizando os testes de software1 2 3 - Testando - Automatizando os testes de software
1 2 3 - Testando - Automatizando os testes de software
Heider Lopes
 
// Não comente seu código, ... - Márcio Torres - Tchelinux Pelotas 2018
// Não comente seu código, ... - Márcio Torres - Tchelinux Pelotas 2018// Não comente seu código, ... - Márcio Torres - Tchelinux Pelotas 2018
// Não comente seu código, ... - Márcio Torres - Tchelinux Pelotas 2018
Tchelinux
 
Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnit
Diego Tremper
 
Palestra Testes Unidade Com JUnit
Palestra Testes Unidade Com JUnitPalestra Testes Unidade Com JUnit
Palestra Testes Unidade Com JUnit
Robinson Castilho
 
Teste de Software - Especialização Univem
Teste de Software - Especialização UnivemTeste de Software - Especialização Univem
Teste de Software - Especialização Univem
André Abe Vicente
 
Testes de Sofware
Testes de SofwareTestes de Sofware
Testes de Sofware
elliando dias
 
Padrões para Desenvolvimento de Software Guiado por Testes
Padrões para Desenvolvimento de Software Guiado por TestesPadrões para Desenvolvimento de Software Guiado por Testes
Padrões para Desenvolvimento de Software Guiado por Testes
Everton Rodrigues
 
TDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fislTDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fisl
Adriano Petrich
 
Workshop: Testes automatizados, Refactoring e Design Patterns
Workshop: Testes automatizados, Refactoring e Design PatternsWorkshop: Testes automatizados, Refactoring e Design Patterns
Workshop: Testes automatizados, Refactoring e Design Patterns
Mauricio Andreazza
 
Palestra Ufpb
Palestra UfpbPalestra Ufpb
Palestra Ufpb
Ítalo Brilhante
 
Fundamentos de Teste de Software - Dev in PF. por Aline Zanin
Fundamentos de Teste de Software - Dev in PF. por Aline ZaninFundamentos de Teste de Software - Dev in PF. por Aline Zanin
Fundamentos de Teste de Software - Dev in PF. por Aline Zanin
DevInPF
 
Code Smells
Code SmellsCode Smells
Code Smells
Rodrigo Branas
 
Getna: Gerador de Código RubyOnRails apartir de banco de dados
Getna: Gerador de Código RubyOnRails apartir de banco de dadosGetna: Gerador de Código RubyOnRails apartir de banco de dados
Getna: Gerador de Código RubyOnRails apartir de banco de dados
Maximusmano
 

Semelhante a Testes com python: como fazer uma refatoração segura (20)

Ctai Teste De Software Aula 1
Ctai Teste De Software Aula 1Ctai Teste De Software Aula 1
Ctai Teste De Software Aula 1
 
PHPUnit e teste de software
PHPUnit e teste de softwarePHPUnit e teste de software
PHPUnit e teste de software
 
Testando Aplicações Django: Quando, Como e Onde?
Testando Aplicações Django: Quando, Como e Onde?Testando Aplicações Django: Quando, Como e Onde?
Testando Aplicações Django: Quando, Como e Onde?
 
Ganhando tempo com casos de testes
Ganhando tempo com casos de testesGanhando tempo com casos de testes
Ganhando tempo com casos de testes
 
Atividades de Teste e Cobertura de Código em Java
Atividades de Teste e Cobertura de Código em JavaAtividades de Teste e Cobertura de Código em Java
Atividades de Teste e Cobertura de Código em Java
 
Introdução ao design de teste de software
Introdução ao design de teste de softwareIntrodução ao design de teste de software
Introdução ao design de teste de software
 
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
 
1 2 3 - Testando - Automatizando os testes de software
1 2 3 - Testando - Automatizando os testes de software1 2 3 - Testando - Automatizando os testes de software
1 2 3 - Testando - Automatizando os testes de software
 
// Não comente seu código, ... - Márcio Torres - Tchelinux Pelotas 2018
// Não comente seu código, ... - Márcio Torres - Tchelinux Pelotas 2018// Não comente seu código, ... - Márcio Torres - Tchelinux Pelotas 2018
// Não comente seu código, ... - Márcio Torres - Tchelinux Pelotas 2018
 
Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnit
 
Palestra Testes Unidade Com JUnit
Palestra Testes Unidade Com JUnitPalestra Testes Unidade Com JUnit
Palestra Testes Unidade Com JUnit
 
Teste de Software - Especialização Univem
Teste de Software - Especialização UnivemTeste de Software - Especialização Univem
Teste de Software - Especialização Univem
 
Testes de Sofware
Testes de SofwareTestes de Sofware
Testes de Sofware
 
Padrões para Desenvolvimento de Software Guiado por Testes
Padrões para Desenvolvimento de Software Guiado por TestesPadrões para Desenvolvimento de Software Guiado por Testes
Padrões para Desenvolvimento de Software Guiado por Testes
 
TDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fislTDD em django sem desculpas versao fisl
TDD em django sem desculpas versao fisl
 
Workshop: Testes automatizados, Refactoring e Design Patterns
Workshop: Testes automatizados, Refactoring e Design PatternsWorkshop: Testes automatizados, Refactoring e Design Patterns
Workshop: Testes automatizados, Refactoring e Design Patterns
 
Palestra Ufpb
Palestra UfpbPalestra Ufpb
Palestra Ufpb
 
Fundamentos de Teste de Software - Dev in PF. por Aline Zanin
Fundamentos de Teste de Software - Dev in PF. por Aline ZaninFundamentos de Teste de Software - Dev in PF. por Aline Zanin
Fundamentos de Teste de Software - Dev in PF. por Aline Zanin
 
Code Smells
Code SmellsCode Smells
Code Smells
 
Getna: Gerador de Código RubyOnRails apartir de banco de dados
Getna: Gerador de Código RubyOnRails apartir de banco de dadosGetna: Gerador de Código RubyOnRails apartir de banco de dados
Getna: Gerador de Código RubyOnRails apartir de banco de dados
 

Último

DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdfDESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
Momento da Informática
 
Manual-de-Credenciamento ANATER 2023.pdf
Manual-de-Credenciamento ANATER 2023.pdfManual-de-Credenciamento ANATER 2023.pdf
Manual-de-Credenciamento ANATER 2023.pdf
WELITONNOGUEIRA3
 
Certificado Jornada Python Da Hashtag.pdf
Certificado Jornada Python Da Hashtag.pdfCertificado Jornada Python Da Hashtag.pdf
Certificado Jornada Python Da Hashtag.pdf
joaovmp3
 
História da Rádio- 1936-1970 século XIX .2.pptx
História da Rádio- 1936-1970 século XIX   .2.pptxHistória da Rádio- 1936-1970 século XIX   .2.pptx
História da Rádio- 1936-1970 século XIX .2.pptx
TomasSousa7
 
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdfTOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
Momento da Informática
 
Logica de Progamacao - Aula (1) (1).pptx
Logica de Progamacao - Aula (1) (1).pptxLogica de Progamacao - Aula (1) (1).pptx
Logica de Progamacao - Aula (1) (1).pptx
Momento da Informática
 

Último (6)

DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdfDESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
 
Manual-de-Credenciamento ANATER 2023.pdf
Manual-de-Credenciamento ANATER 2023.pdfManual-de-Credenciamento ANATER 2023.pdf
Manual-de-Credenciamento ANATER 2023.pdf
 
Certificado Jornada Python Da Hashtag.pdf
Certificado Jornada Python Da Hashtag.pdfCertificado Jornada Python Da Hashtag.pdf
Certificado Jornada Python Da Hashtag.pdf
 
História da Rádio- 1936-1970 século XIX .2.pptx
História da Rádio- 1936-1970 século XIX   .2.pptxHistória da Rádio- 1936-1970 século XIX   .2.pptx
História da Rádio- 1936-1970 século XIX .2.pptx
 
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdfTOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
 
Logica de Progamacao - Aula (1) (1).pptx
Logica de Progamacao - Aula (1) (1).pptxLogica de Progamacao - Aula (1) (1).pptx
Logica de Progamacao - Aula (1) (1).pptx
 

Testes com python: como fazer uma refatoração segura

  • 1. 1 Testes com Python: Como fazer uma refatoração segura
  • 2. 2 Sobre o apresentador Valberto Vieira Carneiro Analista de Tecnologia da Informação - IFPB Especialista em Qualidade e Testes de Software
  • 3. 3 Roteiro 1. Estudo de caso 2. Motivação 3. Por onde começar? 4. Conceitos 5. Testes 6. Refatoração 7. Dicas
  • 4. 4 Estudo de caso Módulo de diárias e passagens do Instituto Federal da Paraíba
  • 5. 5 Fluxo para solicitar diárias e passagens
  • 6. 6 Fluxo para prestar contas da viagem realizada
  • 7. 7 Meu Objetivo Aplicar melhorias em um sistema que já está em produção. Situação Possui uma lista com novos requisitos Não possui nenhum teste Possui manual de usuário
  • 8. 8 Sentimentos Vamos arrumar a casa Preciso entender como esse código funciona Será que vai dar certo?
  • 9. 9 Motivação Vamos deixar os testes para depois! Não temos tempo! Na minha máquina funciona!
  • 10. 10 Testar e refatorar, como fazer? O que testar e o que não testar? Qual tipo de testes usar?
  • 11. 11 Por onde começar? Tenha um objetivo bem definido Verifique se o módulo possui documentação Faça um teste exploratório nas principais funcionalidades Estude sobre refatoração
  • 13. 13 O que é teste de software? Os testes são realizados com a intenção de descobrir defeitos em um sistema. [Myres, 2004] Os testes de software podem ser usados para mostrar a presença de defeitos, mas nunca para mostrar a ausência deles. [Dijkstra, 1972]
  • 14. 14 Caixa branca Código fonte Testes unitários Caixa preta Requisitos Testes funcionais Tipos de testes
  • 15. 15 Práticas que poderiam ajudar? Fonte: http://www.aniche.com.br/tdd/ TDD - Test Driven Development - Escrever o teste antes de codificar
  • 16. 16 Requisitos - Regras de negócio - Segurança - Permissões de usuários - - Framework - Métodos nativos - Requisitos com baixo valor de negócio** O que testar e o que não testar?
  • 17. 17 Dicas - Comece pelo mais simples! - Evolua os testes gradativamente - As vezes será necessário reorganizar os testes - Teste o fluxo principal - Teste a(s) funcionalidade(s) mais importante(s)
  • 18. 18 Exemplos: teste funcional básico from django.test import TestCase class HomologadorTestCase(TestCase): def test_pagina_inicial(self): response = self.client.get('/') self.assertEqual(response.status_code, 200) self.assertContains(response, u"Título da página") $ ./manage.py test expedicao
  • 19. 19 Exemplos: afirmações - assertEqual(a, b) # a == b - assertNotEqual(a, b) # a <> b - assertTrue(bool) # True - assertFalse(bool) # False - assertRaises(Exception) # raise Exception - assertIn(a, b) # a in b - assertNotIn(a, b) # a not in b - assertGreater(a, b) # a > b - assertLess(a, b) # a < b
  • 20. 20 Exemplos: teste no Suap from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def test_pode_ver_aba_homologador(self): self.logout() successful = self.client.login(username=self.user.username, password='123') self.assertEqual(successful, True) url = "/admin/expedicao/viagemservidor/" response = self.client.get(url, follow=True) self.assertContains(response, u"tab_viagens_homologar")
  • 21. 21 from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def test_pode_ver_aba_homologador(self): self.logout() successful = self.client.login(username=self.user.username, password='123') self.assertEqual(successful, True) url = "/admin/expedicao/viagemservidor/" response = self.client.get(url, follow=True) self.assertContains(response, u"tab_viagens_homologar") Exemplos: teste no Suap
  • 22. 22 from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def acessar_como(self, user): self.logout() successful = self.client.login(username=user.username, password='123') self.assertEqual(successful, True) def test_pode_ver_aba_homologador(self): self.acessar_como(self.homologador) url = "/admin/expedicao/viagemservidor/" response = self.client.get(url, follow=True) self.assertContains(response, u"tab_viagens_homologar") Exemplos: teste no Suap
  • 23. 23 from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def acessar_como(self, user): self.logout() successful = self.client.login(username=user.username, password='123') self.assertEqual(successful, True) def test_pode_ver_aba_homologador(self): self.acessar_como(self.homologador) url = "/admin/expedicao/viagemservidor/" response = self.client.get(url, follow=True) self.assertContains(response, u"tab_viagens_homologar") Exemplos: teste no Suap
  • 24. 24 from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def acessar_como(self, user): def test_pode_ver_aba_homologador(self): self.acessar_como(self.homologador) url = "/admin/expedicao/viagemservidor/" response = self.client.get(url, follow=True) self.assertContains(response, u"tab_viagens_homologar") Exemplos: teste no Suap
  • 25. 25 from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def acessar_como(self, user): def test_pode_ver_aba_homologador(self): self.acessar_como(self.homologador) url = "/admin/expedicao/viagemservidor/" response = self.client.get(url, follow=True) self.assertContains(response, u"tab_viagens_homologar") Exemplos: teste no SuapChangelist {{ app_label }}_{{ model_name }}_changelist Add {{ app_label }}_{{ model_name }}_add /add History {{ app_label }}_{{ model_name }}_history /id/history Delete {{ app_label }}_{{ model_name }}_delete /id/delete Change {{ app_label }}_{{ model_name }}_change /id 'expedicao_viagemservidor_changelist' '/admin/expedicao/viagemservidor/'
  • 26. 26 from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def acessar_como(self, user): def get_changelist_page(cls): ... def test_pode_ver_aba_homologador(self): self.acessar_como(self.homologador) response = self.get_changelist_page(models.ViagemServidor) self.assertContains(response, u"tab_viagens_homologar") Exemplos: teste no Suap
  • 27. 27 from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def acessar_como(self, user): def get_changelist_page(cls): def test_pode_ver_aba_homologador(self): self.acessar_como(self.homologador) response = self.get_changelist_page(models.ViagemServidor) self.assertContains(response, u"tab_viagens_homologar") Exemplos: teste no Suap
  • 28. 28 from django.test import TestCase class SuapTestCase(TestCase): class ExpedicaoTestCase(SuapTestCase): class HomologadorTestCase(ExpedicaoTestCase): def acessar_como(self, user): def get_changelist_page(cls): def test_pode_ver_aba_homologador(self): self.acessar_como(self.homologador) response = self.get_changelist_page(models.ViagemServidor) self.assertContains(response, u"tab_viagens_homologar") # self.logout() # successful = self.client.login(username=self.user.username, password='123') # self.assertEqual(successful, True) # url = "/admin/expedicao/viagemservidor/" # response = self.client.post(url, follow=True) # self.assertContains(response, u"tab_viagens_homologar") Exemplos: teste no Suap
  • 30. 30 Refatorar é… um processo disciplinado de alterar o código de um sistema sem alterar o seu comportamento observável buscando melhorar a estrutura interna e minimizando a chance de introdução de novas falhas. (Martin Fowler, Kent Beck) Exige experiência e envolve uma grande responsabilidade.
  • 31. 31 Refatorar não é… Alterar o código adicionando novos recursos Reescrever ou substituir grande partes do código
  • 32. 32 Etapas 1. Detecção de oportunidades de refactoring 2. Decisão do Uso (custos e benefícios) 3. Preparação da avaliação 4. Execução de um dado refactoring 5. Avaliação
  • 33. 33 Etapa 1: Detecção de oportunidades de refactoring Code smell é como se aquele trecho de código cheirasse e você sabe que precisa ser refatorado Problemas mais comuns código duplicado | método longo | classes grandes comandos switch | campo temporário classe ociosa | comentários pylint
  • 34. 34 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Comentário longo. - Comentário desnecessário. - Comentário não condiz com o objetivo do método. - Imports não utilizados. - Método/código duplicado comum.utils.get_funcionario. - Linhas com mais de 80 caracteres. - Método muito extenso. - Número mágico. - Nome muito grande para uma variável (23 caracteres).
  • 35. 35 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Comentário longo. - Comentário desnecessário. - Comentário não condiz com o objetivo do método. - Imports não utilizados. - Método/código duplicado comum.utils.get_funcionario. - Linhas com mais de 80 caracteres. - Método muito extenso. - Número mágico. - Nome muito grande para uma variável (23 caracteres). # Cria o relatório referente a esta viagem relatorio = RelatorioViagem(viagem=viagem) relatorio.save()
  • 36. 36 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Comentário longo. - Comentário desnecessário. - Comentário não condiz com o objetivo do método. - Imports não utilizados. - Método/código duplicado comum.utils.get_funcionario. - Linhas com mais de 80 caracteres. - Método muito extenso. - Número mágico. - Nome muito grande para uma variável (23 caracteres). if (data.isoweekday() >= 6):
  • 37. 37 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Comentário longo. - Comentário desnecessário. - Comentário não condiz com o objetivo do método. - Imports não utilizados. - Método/código duplicado comum.utils.get_funcionario. - Linhas com mais de 80 caracteres. - Método muito extenso. - Número mágico. - Nome muito grande para uma variável (23 caracteres). SABADO, DOMINGO = 6, 7 if data.isoweekday() in [SABADO, DOMINGO]:
  • 38. 38 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Aquivo não tem limitador de extensão nem de tamanho. - Extrair consulta para um método. - Nomenclatura não exite mais. - Condições complexas demais. Substituir por método: is_empty(nome_campo). - Substituir condições negativas por uma afirmativas.
  • 39. 39 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Aquivo não tem limitador de extensão nem de tamanho. - Extrair consulta para um método. - Nomenclatura não exite mais. - Condições complexas demais. Substituir por método: is_empty(nome_campo). - Substituir condições negativas por uma afirmativas. arquivo = models.FileField( upload_to='/comprovantes/', verbose_name=u'Comprovante')
  • 40. 40 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Aquivo não tem limitador de extensão nem de tamanho. - Extrair consulta para um método. - Nomenclatura não exite mais. - Condições complexas demais. Substituir por método: is_empty(nome_campo). - Substituir condições negativas por uma afirmativas. arquivo = models.FileField( upload_to='/comprovantes/', verbose_name=u'Comprovante', help_text=u'Tamanho máximo 2MB.', validators=[FileValidator()])
  • 41. 41 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Aquivo não tem limitador de extensão nem de tamanho. - Extrair consulta para um método. - Nomenclatura não exite mais. - Condições complexas demais. Substituir por método: is_empty(nome_campo). - Substituir condições negativas por uma afirmativas. historico = HistoricoSolicitacao.objects. filter(viagem=self). order_by('-data'). all()[0] historico = self.historicos.latest('data')
  • 42. 42 Exemplos: detecção dos pontos de melhoria # TODO refactory: - Aquivo não tem limitador de extensão nem de tamanho. - Extrair consulta para um método. - Nomenclatura não exite mais. - Condições complexas demais. Substituir por método: is_empty(nome_campo). - Substituir condições negativas por uma afirmativas. def ultimo_historico(): return self.historicos.latest('data') historico = ultimo_historico()
  • 43. 43 Etapa 2: Decisão do Uso (custos e benefícios) Custos e benefícios Tempo e esforço necessários valerão a pena? Decisão não automatizada Código duplicado: Extrair Método, Extrair Classe, Subir Método na Hierarquia ou Substituir Algoritmo
  • 44. 44 Etapa 3: Preparação da avaliação Desenvolver testes Garantir que o comportamento do sistema seja mantido Decidir qual tipo de testes Testes funcionais Caixa preta
  • 45. 45 Dicas Crie grupos de funções que deseja testar - perfil de usuário (testar acesso e negação de acesso) - fluxo de negócio - regras de negócio (validações)
  • 46. 46 Exemplos: Preparação da avaliação class ExpedicaoTestCase(SuapTestCase): Testes Tempo class AdministradorTestCase(ExpedicaoTestCase): | 4 | 00:00:38 | class ExecutorTestCase(ExpedicaoTestCase): | 4 | 00:00:02 | class HomologadorTestCase(ExpedicaoTestCase): | 1 | 00:00:00 | class AutorizadorUOTestCase(ExpedicaoTestCase): | 2 | 00:00:01 | class ChefeTestCase(ExpedicaoTestCase): | 5 | 00:00:03 | class SubstitutoTestCase(ExpedicaoTestCase): | 4 | 00:00:03 | class ViagemServidorTestCase(ExpedicaoTestCase): | 14 | 00:00:11 | class RelatorioViagemTestCase(ExpedicaoTestCase):| 7 | 00:00:09 | TOTAL: 41 | 00:01:12 | Cobertura 72% $ pip install coverage
  • 47. 47 Etapa 4: Execução de um dado refactoring Aplicar as refatorações Objetivo é eliminar o code smell Qual o momento certo? Atividade contínua, integrada ao desenvolvimento: - Acrescentar uma função - Consertar uma falha - Revisar o código
  • 48. 48 Exemplos: Aplicar refatorações def relatorio_detail(request, id): title = u'Relatório do Servidor' usuario = request.user try: relatorio = RelatorioViagem.objects.get(id=id) except RelatorioViagem.DoesNotExist: return HttpResponseBadRequest(u'O relatório não existe!') if not (eh_dono_viagem(request, relatorio.viagem.id) or eh_ordenador(request) or eh_executor(request) or usuario.eh_chefe_do_setor(usuario.setor)): raise PermissionDenied return locals()
  • 49. 49 Exemplos: Aplicar refatorações def relatorio_detail(request, id): title = u'Relatório do Servidor' usuario = request.user try: relatorio = RelatorioViagem.objects.get(id=id) except RelatorioViagem.DoesNotExist: return HttpResponseBadRequest(u'O relatório não existe!') if not (eh_dono_viagem(request, relatorio.viagem.id) or eh_ordenador(request) or eh_executor(request) or usuario.eh_chefe_do_setor(usuario.servidor.setor)): raise PermissionDenied return locals() relatorio = get_object_or_404(RelatorioViagem, pk=id)
  • 50. 50 Exemplos: Aplicar refatorações def relatorio_detail(request, id): title = u'Relatório do Servidor' usuario = request.user relatorio = get_object_or_404(RelatorioViagem, pk=id) if not (eh_dono_viagem(request, relatorio.viagem.id) or eh_ordenador(request) or eh_executor(request) or usuario.eh_chefe_do_setor(usuario.setor)): raise PermissionDenied return locals()
  • 51. 51 Exemplos: Aplicar refatorações def relatorio_detail(request, id): title = u'Relatório do Servidor' usuario = request.user relatorio = get_object_or_404(RelatorioViagem, pk=id) if not (eh_dono_viagem(request, relatorio.viagem.id) or eh_ordenador(request) or eh_executor(request) or usuario.eh_chefe_do_setor(usuario.setor)): raise PermissionDenied return locals() regra = regras.RelatorioViagemRegras(relatorio) if not regra.pode_ver(request.user): raise PermissionDenied
  • 52. 52 Exemplos: Aplicar refatorações def relatorio_detail(request, id): title = u'Relatório do Servidor' relatorio = get_object_or_404(RelatorioViagem, pk=id) regra = regras.RelatorioViagemRegras(relatorio) if not regra.pode_ver(request.user): raise PermissionDenied return locals()
  • 53. Etapa 5: Avaliação O comportamento é o mesmo? Analisar resultado dos testes Realizar análise cognitiva Buscar novo code smell 53
  • 56. 56 Referências - CARNEIRO, Glauco de F. Usando medição de código fonte para refactoring. Abril de 2003. 123 p. Dissertação (Mestrado Profissional em Redes de Computadores) - Universidade Salvador, Salvador, 2003. - Dijkstra, E. W. "The Humble Programmer". Communications of the ACM 15 (10): 859–866, 1972. - Entendendo Testes de Software https://willianjusten.com.br/entendendo-testes-de-software/ - FOWLER, Martin et al. Refatoração: Aperfeiçoando o Projeto de Código Existente. trad.Acauan Fernandes – Porto Alegre: Bookman, 2004. - Improve Your Python: Understanding Unit Testing https://jeffknupp.com/blog/ - List for code-quality tools related to Python https://mail.python.org/mailman/listinfo/code-quality - Myres , G. F. “The Art of Software Testing”. Ed. John Wiley & Sons, Inc. New Jersey, 2004. - O que é e o que não é refatoração – de acordo com Kent Beck e Martin Fowler https://dzone.com/articles/what-refactoring-and-what-it-0 - Os 10 princípios dos Testes de Software http://gtsw.blogspot.com.br/2007/12/os-princpios-dos-testes-de-software.html - Refactoring Patterns https://dzone.com/refcardz/refactoring-patterns - Review of Python Static Analysis Tools http://blog.codacy.com/2016/01/08/review-of-python-static-analysis-tools/ - Start Here: Introductions to Python Testing Frameworks http://pythontesting.net/start-here/ - Testes e Refatoração http://pt.slideshare.net/jeveaux/testes-e-refatorao-presentation-622966 - Writing unit tests in Python: How do I start? http://stackoverflow.com/questions/3371255/writing-unit-tests-in-python-how-do-i-start