53
simple is better than complex The Zen of Python (import this) lidade levada a sério em Python

Qualidade levada a sério em Python - Emilio Simoni

Embed Size (px)

Citation preview

Page 1: Qualidade levada a sério em Python - Emilio Simoni

simple is better than complexThe Zen of Python (import this)

Qualidade levada a sério em Python

Page 2: Qualidade levada a sério em Python - Emilio Simoni

• Master Coaching Trainer• Pesquisador de segurança sênior

• Programador C/C++ e Python• Data Scientist

• Viciado em competições de ML

• Coordenador equipe ameaças PSafe

Page 3: Qualidade levada a sério em Python - Emilio Simoni

5° software mais baixadoMaior empresa mobile LA200 mil downloads/dia

Page 4: Qualidade levada a sério em Python - Emilio Simoni
Page 5: Qualidade levada a sério em Python - Emilio Simoni

PessoasProcesso

Produto

Page 6: Qualidade levada a sério em Python - Emilio Simoni

Versionamento

QualidadeAutomatização

RequisitosMetodologia

Processo = Engenharia de software

Page 7: Qualidade levada a sério em Python - Emilio Simoni

Testes

Analise estática

Bug Tracking

Documentação

Page 8: Qualidade levada a sério em Python - Emilio Simoni
Page 9: Qualidade levada a sério em Python - Emilio Simoni
Page 10: Qualidade levada a sério em Python - Emilio Simoni

Teste

s au

tom

atiza

dos

Page 11: Qualidade levada a sério em Python - Emilio Simoni

Testes de software

Page 12: Qualidade levada a sério em Python - Emilio Simoni
Page 13: Qualidade levada a sério em Python - Emilio Simoni
Page 14: Qualidade levada a sério em Python - Emilio Simoni
Page 15: Qualidade levada a sério em Python - Emilio Simoni

Específicos

Auto descritivos

Auto suficientes

Indicar o comportamento esperado

Servir de documentação

Bugs tendem a virar um caso de teste

Unit Tests

Page 16: Qualidade levada a sério em Python - Emilio Simoni

PyUnit

Unit Tests

assertTrue

assertEqual

assertAlmostEqual

assertIn

Page 17: Qualidade levada a sério em Python - Emilio Simoni

Mão na massa!

Page 18: Qualidade levada a sério em Python - Emilio Simoni

Test Fixture

Test Case

Test Suite

Test Runner

Unit Tests

Page 19: Qualidade levada a sério em Python - Emilio Simoni

Test Fixture

Page 20: Qualidade levada a sério em Python - Emilio Simoni

Test Fixtureclass SimpleTestCase(unittest.TestCase):

def setUp(self):"""Call before every test case.""“self.foo = Foo()self.file = open( "blah", "r" )

def tearDown(self):"""Call after every test case.""“self.file.close()

Page 21: Qualidade levada a sério em Python - Emilio Simoni

OQueTaSendoTestando_Parametros_RetornoEsperadoget_client_name__with_invalid__params_must_return_False

Test Case

Page 22: Qualidade levada a sério em Python - Emilio Simoni

def test_get_client_name__with_invalid__params_must_return_False (self):"""Test case 1. note that all test method names must begin with 'test.'""“ self.assertEqual(foo.get_client_name(None) , False)

OQueTaSendoTestando_Parametros_RetornoEsperadoget_client_name__with_invalid__params_must_return_False

Page 23: Qualidade levada a sério em Python - Emilio Simoni

import unittestfrom foobarbaz import Foo # code from module you're testing

class SimpleTestCase(unittest.TestCase):def setUp(self):

"""Call before every test case.""“self.foo = Foo()self.file = open( "blah", "r" )

def tearDown(self):"""Call after every test case.""“self.file.close()

def test_get_client_name__with_invalid__params_must_return_False (self):"""Test case 1. note that all test method names must begin with 'test.'""“ self.assertEqual(foo.get_client_name(None) , False)

Test Suite

Page 24: Qualidade levada a sério em Python - Emilio Simoni

Gerencia os testes e fornece uma interface de acesso.

Test Runner

Page 25: Qualidade levada a sério em Python - Emilio Simoni
Page 26: Qualidade levada a sério em Python - Emilio Simoni

Teste se torna o primeiro cliente do seu código

Somente o codigo necessario é criado

Erros são identificados mais rapidamente

Ganho de produtividade

Códigos entregues realmente prontos

Facilita depuração

Page 27: Qualidade levada a sério em Python - Emilio Simoni

Integration Tests

Page 28: Qualidade levada a sério em Python - Emilio Simoni

Integration Testsdef test_add_source_must_check_duplicated(self): psw = PhishingServiceWrapper() psw.add_url('http://www.testededominio.com.br', source_id=1) add_ret = psw.add_url('http://www.testededominio.com.br', source_id=1)

self.assertEqual(add_ret['status'], 'duplicated')

Page 29: Qualidade levada a sério em Python - Emilio Simoni

Performance Tests

Page 30: Qualidade levada a sério em Python - Emilio Simoni

Performance Tests

__main__.SomeTest.testOne: 1.001 __main__.SomeTest.testTwo: 2.002 -----------------------------------------------

Ran 2 tests in 3.003s OK

Page 31: Qualidade levada a sério em Python - Emilio Simoni

Performance Testsimport cProfileimport unittest if __name__ == '__main__':   suite = unittest.TestLoader().discover('.')   def runtests():      unittest.TextTestRunner().run(suite)   cProfile.run('runtests()',sort='cumtime')

Page 32: Qualidade levada a sério em Python - Emilio Simoni

Performance Tests

25510 function calls (25298 primitive calls) in 0.820 seconds

Ordered by: cumulative time

ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.820 0.820 <string>:1(<module>)

Page 33: Qualidade levada a sério em Python - Emilio Simoni

Performance Tests

def test_add_source_must_check_duplicated(self): import time psw = PhishingServiceWrapper() before_functiion = time.time() psw.add_url('http://www.testededominio.com.br', source_id=1) after_functiion = time.time()

self.assertLess(after_functiion - before_function, 1.0)

Page 34: Qualidade levada a sério em Python - Emilio Simoni

Performance Tests@profiledef primes(n): if n==2: return [2] elif n<2: return [] s=range(3,n+1,2) mroot = n ** 0.5 half=(n+1)/2-1 i=0 m=3 while m <= mroot: if s[i]: j=(m*m-3)/2 s[j]=0 while j<half: s[j]=0 j+=m i=i+1 m=2*i+3 return [2]+[x for x in s if x]primes(100)

pip install line_profiler

kernprof -l –v primes.py

Page 35: Qualidade levada a sério em Python - Emilio Simoni

Performance TestsLine # Hits Time Per Hit % Time Line Contents============================================================== 2 @profile 3 def primes(n): 4 1 2 2.0 1.1 if n==2: 5 return [2] 6 1 1 1.0 0.5 elif n<2: 7 return [] 8 1 4 4.0 2.1 s=range(3,n+1,2) 9 1 10 10.0 5.3 mroot = n ** 0.5 10 1 2 2.0 1.1 half=(n+1)/2-1 11 1 1 1.0 0.5 i=0 12 1 1 1.0 0.5 m=3 13 5 7 1.4 3.7 while m <= mroot: 14 4 4 1.0 2.1 if s[i]: 15 3 4 1.3 2.1 j=(m*m-3)/2 16 3 4 1.3 2.1 s[j]=0 17 31 31 1.0 16.3 while j<half: 18 28 28 1.0 14.7 s[j]=0 19 28 29 1.0 15.3 j+=m 20 4 4 1.0 2.1 i=i+1 21 4 4 1.0 2.1 m=2*i+3 22 50 54 1.1 28.4 return [2]+[x for x in s if x]

Page 36: Qualidade levada a sério em Python - Emilio Simoni

Performance Tests

python -m memory_profiler primes.py

pip install memory_profiler

Page 37: Qualidade levada a sério em Python - Emilio Simoni

Performance2 @profile 3 7.9219 MB 0.0000 MB def primes(n): 4 7.9219 MB 0.0000 MB if n==2: 5 return [2] 6 7.9219 MB 0.0000 MB elif n<2: 7 return [] 8 7.9219 MB 0.0000 MB s=range(3,n+1,2) 9 7.9258 MB 0.0039 MB mroot = n ** 0.5 10 7.9258 MB 0.0000 MB half=(n+1)/2-1 11 7.9258 MB 0.0000 MB i=0 12 7.9258 MB 0.0000 MB m=3 13 7.9297 MB 0.0039 MB while m <= mroot: 14 7.9297 MB 0.0000 MB if s[i]: 15 7.9297 MB 0.0000 MB j=(m*m-3)/2 16 7.9258 MB -0.0039 MB s[j]=0 17 7.9297 MB 0.0039 MB while j<half: 18 7.9297 MB 0.0000 MB s[j]=0 19 7.9297 MB 0.0000 MB j+=m 20 7.9297 MB 0.0000 MB i=i+1 21 7.9297 MB 0.0000 MB m=2*i+3 22 7.9297 MB 0.0000 MB return [2]+[x for x in s if x]

Page 38: Qualidade levada a sério em Python - Emilio Simoni

Bug Tracking

Page 39: Qualidade levada a sério em Python - Emilio Simoni

Bug Trackingimport unittestfrom foobarbaz import Foo

class SimpleTestCase(unittest.TestCase):def setUp(self):

"""Call before every test case.""“self.foo = Foo()self.file = open( "blah", "r" )

def tearDown(self):"""Call after every test case.""“self.file.close()

def test_get_client_name__with_big_param__must_return_False (self): self.assertEqual(foo.get_client_name(“A” * 1024*1024) , False)

Page 40: Qualidade levada a sério em Python - Emilio Simoni

Analise estática

Page 41: Qualidade levada a sério em Python - Emilio Simoni

Analise estáticaChecar idioma

Documentação de codigo

Compliance

Erros

Codigos duplicados ou complexos

pylint file.py

pip install pylint

Page 42: Qualidade levada a sério em Python - Emilio Simoni

Analise estática

Page 43: Qualidade levada a sério em Python - Emilio Simoni

Analise estática

radonpip install radon

Complexidade ciclomática

Linhas de código, comentários, ...

Maintainability Index

Page 44: Qualidade levada a sério em Python - Emilio Simoni

Analise estática

Page 45: Qualidade levada a sério em Python - Emilio Simoni

Analise estática

Page 46: Qualidade levada a sério em Python - Emilio Simoni

Analise estática

Page 47: Qualidade levada a sério em Python - Emilio Simoni

Analise estática

Page 48: Qualidade levada a sério em Python - Emilio Simoni

DocumentaçãoDocStrings

Documentação simples e clara, não deve conter detalhes da implementação

Documentação ruim é pior do que não documentado

Sumarizar o comportamento da função

Argumentos, retornos, exceções disparadas e restrições.

Não documentar o obvio

Page 49: Qualidade levada a sério em Python - Emilio Simoni

Documentação

Page 50: Qualidade levada a sério em Python - Emilio Simoni

import thissimple is better than complex

Page 51: Qualidade levada a sério em Python - Emilio Simoni

pep-0020The Zen of Python

Page 52: Qualidade levada a sério em Python - Emilio Simoni

Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!