Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código Ferramentas de teste para a linguagem Python coverage.py Profiling Python profiler IDEs eric3 PyDev José Fonseca Faculdade de Engenharia da Universidade do Porto Outras ferramentas 17 Maio 2005, Teste e Qualidade de Software Estrutura da apresentação Ferramentas de teste para a linguagem Python 1 Introdução à linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling 2 Ferramentas para testes unitários doctest PyUnit 3 Ferramentas para cobertura de código coverage.py Python profiler IDEs eric3 PyDev Outras ferramentas 4 Ferramentas para profiling Python profiler 5 IDEs eric3 PyDev 6 Outras ferramentas Python – Breve descrição da linguagem Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas interpretada interactiva orientada por objectos (tudo é um objecto, herança múltipla) introspectiva sintaxe elegante (indentação faz parte da sintaxe) suporte nativo para alguns tipos de dados de alto nı́vel (string, list, dictionary) biblioteca rica (expressões regulares, HTTP, XML, . . . ) extensı́vel (com módulos compilados em C ou C++) embebı́vel noutra aplicação (ABAQUS, Blender, Paint Shop Pro 8, Vim, . . . ) portável (Unix, Windows, Mac OS, Nokia S60, . . . ) vários toolkits gráficos disponı́veis (TK, GTK, QT, wxWidgets, ...) Python – Exemplo de uma sessão interactiva Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas $ python Python 2.3.5 (#2 , Mar 27 2005 , 09:43:31) [ GCC 3.3.5 ( Debian 1:3.3.5 -12) ] on linux2 Type " help " , " copyright " , " credits " or " license " for more information . >>> tax = 12.5 /100 >>> price = 100.50 >>> price * tax 12.5625 >>> price + _ 113.0625 >>> round (_ , 2) 113.06 >>> Python – Exemplo de uma função Ferramentas de teste para a linguagem Python José Fonseca ex func.py Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler def prime(n): ”””Retorna verdadeiro ou falso consoante n é um número primo.””” for i in range(2, n): # ciclo de 2 a n−1 if not n % i: # resto da divisão inteira return False return True IDEs eric3 PyDev print prime(10) print prime(11) Outras ferramentas $ python ex_func . py False True Python – Exemplo de uma classe Ferramentas de teste para a linguagem Python José Fonseca ex class.py class Complex: ”””Representação de um número complexo.””” Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas def init (self, real=0.0, imag=0.0): ”””Constructor.””” self.real = real self.imag = imag def mul (self, other): ”””Produto de dois números complexos.””” return Complex( self.real∗other.real − self.imag∗other.imag, self.real∗other.imag + self.imag∗other.real) def conj(self): return Complex(self.real, −self.imag) def str (self): ”””Representação textual do número.””” return ”%g+%gi” % (self.real, self.imag) # formatação a = Complex(1,2) print a print a∗a.conj() Python – Exemplo de uma classe Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas $ python ex_class . py 1+2 i 5+0 i Python – Mais informação Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python homepage http://www.python.org/ Python Introduction http://www.python.org/doc/Introduction.html Python profiler IDEs eric3 PyDev Outras ferramentas Python Tutorial http://www.python.org/doc/current/tut/ doctest – Descrição Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Procura na própria documentação do código a especificação de casos de teste. Os casos de teste servem quer para verificação quer para exemplificação do uso. Pode ser usado em módulos, funções, classes e métodos. Parte da biblioteca standard da linguagem. Também pode ser integrado com a framework PyUnit. doctest – Exemplo Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas ex doctest.py def factorial(n): ”””Return the factorial of n, an exact integer >= 0. If the result is small enough to fit in an int, return an int. Else return a long. >>> [factorial(n) for n in range(6)] [1, 1, 2, 6, 24, 120] >>> factorial(30) 265252859812191058636308480000000L >>> factorial(−1) Traceback (most recent call last): ... ValueError: n must be >= 0 Factorials of floats are OK, but the float must be an exact integer: >>> factorial(30.1) Traceback (most recent call last): ... ValueError: n must be exact integer It must also not be ridiculously large: >>> factorial(1e100) Traceback (most recent call last): ... OverflowError: n too large ””” doctest – Exemplo Ferramentas de teste para a linguagem Python José Fonseca import math if not n >= 0: raise ValueError(”n must be >= 0”) if math.floor(n) != n: raise ValueError(”n must be exact integer”) if n+1 == n: # catch a value like 1e300 raise OverflowError(”n too large”) result = 1 factor = 2 while factor <= n: result ∗= factor factor += 1 return result Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas if name == ” main ”: import doctest doctest.testmod() doctest – Exemplo Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas $ python ex_doctest . py -v Running __main__ . __doc__ 0 of 0 examples failed in __main__ . __doc__ Running __main__ . factorial . __doc__ Trying : [ factorial ( n ) for n in range (6) ] Expecting : [1 , 1 , 2 , 6 , 24 , 120] ok Trying : factorial (30) Expecting : 2 6 5 2 5 2 8 5 9 8 1 2 1 9 1 0 5 8 6 3 6 3 0 8 4 8 0 0 0 0 0 0 0 L ok Trying : factorial ( -1) Expecting : Traceback ( most recent call last ) : ... ValueError : n must be >= 0 ok Trying : factorial (30.1) Expecting : Traceback ( most recent call last ) : ... ValueError : n must be exact integer ok Trying : factorial (1 e100 ) Expecting : Traceback ( most recent call last ) : ... OverflowError : n too large ok 0 of 5 examples failed in __main__ . factorial . __doc__ 1 items had no tests : __main__ 1 items passed all tests : 5 tests in __main__ . factorial 5 tests in 2 items . 5 passed and 0 failed . Test passed . doctest – Mais informação Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Manual de referência do módulo doctest http://docs.python.org/lib/module-doctest.html Testing frameworks in Python http://www.ibm.com/developerworks/linux/library/l-cptest.html PyUnit – Descrição Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas É uma versão em Python da framework JUnit. Suporta a automação de testes, a partilha de código de inicialização e finalização de testes, a agregação de testes em colecções, e a separação entre os testes e a interface com o utilizador. Incluı́da na biblioteca standard desde a versão 2.1 da linguagem. PyUnit – Exemplo Ferramentas de teste para a linguagem Python José Fonseca ex unittest.py import random # módulo a testar import unittest # definição da classe para casos de teste Introdução class TestSequenceFunctions(unittest.TestCase): Testes unitários doctest PyUnit def setUp(self): self.seq = range(10) Cobertura de código def testshuffle(self): # certifica que a sequência baralhada não perdeu elementos random.shuffle(self.seq) self.seq.sort() self.assertEqual(self.seq, range(10)) coverage.py Profiling Python profiler IDEs eric3 PyDev def testchoice(self): element = random.choice(self.seq) self.assert (element in self.seq) Outras ferramentas def testsample(self): self.assertRaises(ValueError, random.sample, self.seq, 20) for element in random.sample(self.seq, 5): self.assert (element in self.seq) if name == ’ main ’: unittest.main() PyUnit – Exemplo Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas $ python ex_unittest . py -v testchoice ( __main__ . T e s t S e q u e n c e F u n c t i o n s ) ... ok testsample ( __main__ . T e s t S e q u e n c e F u n c t i o n s ) ... ok testshuffle ( __main__ . T e s t S e q u e n c e F u n c t i o n s ) ... ok ---------------------------------------------------------------------Ran 3 tests in 0.000 s OK PyUnit – Mais informação Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Manual de referência do módulo unittest http://docs.python.org/lib/module-unittest.html PyUnit homepage http://pyunit.sf.net/ Testing frameworks in Python http://www.ibm.com/developerworks/linux/library/l-cptest.html Dive Into Python: Unit Testing http://www.diveintopython.org/unit_testing/ coverage.py – Descrição Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas É um módulo em Python que mede a cobertura de linhas de código durante a execução. Usa as ferramentas de análise de código e as callbacks de depuração de código fornecidas pela biblioteca standard da linguagem para determinar quais as linhas executáveis e quais foram executadas, respectivamente. Acumula a informação das instruções executadas ao longo de várias execuções. Gera relatórios e/ou anota o código fonte com as linhas cobertas. coverage.py – Exemplo Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit ex coverage.py def abs(x): if x < 0: return −x else: return x print abs(−1) Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev $ python coverage . py -e $ python coverage . py -x ex_coverage . py $ python coverage . py -r -m ex_coverage . py Name Stmts Exec Cover Missing ------------------------------------------ex_coverage 5 4 80% 5 $ python coverage . py -a ex_coverage . py Outras ferramentas ex coverage.py anotado 1 2 3 4 5 6 7 > def abs ( x ) : > i f x < 0: > r e t u r n −x ! else : ! return x > p r i n t a b s (−1) coverage.py – Mais informação Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas coverage homepage http://www.nedbatchelder.com/code/modules/coverage.html Statement coverage for Python http://www.garethrees.org/2001/12/04/python-coverage/ Python profiler – Descrição Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Profiling determinı́stico de qualquer programa em Python. Ferramentas para gerar relatórios de modo a permitir examinar os resultados da operação de profiling. Parte integrante da biblioteca nativa da linguagem Python. Python profiler – Estatı́sticas por função Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas ncalls número de chamadas tottime tempo total gasto na função (excluindo o tempo gasto em chamadas a sub-funções) percall quociente de tottime por ncalls cumtime tempo total gasto na função e todas as sub-funções (desde a invocação até ao retorno) percall quociente de percall por ncalls filename:lineno(function) referência à função Python profiler – Exemplo 1 Ferramentas de teste para a linguagem Python José Fonseca ex profile1.py Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler def ismultiple(n, i): return n % i == 0 def isprime(n): for i in range(2,n): if ismultiple(n, i): return False return True IDEs eric3 PyDev Outras ferramentas def main(): for i in range(2,1000): if isprime(i): print i, print main() Python profiler – Exemplo 2 Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas ex profile2.py primes = [] # guardar os primos anteriores def ismultiple(n, i): return n % i == 0 def isprime(n): import math global primes sn = int(math.sqrt(n)) for i in primes: if i > sn: # terminar na raiz quadrada break if ismultiple(n, i): return False primes.append(n) return True def main(): for i in range(2,1000): if isprime(i): print i, print main() Python profiler – Resultados Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas $ python -m profile ex_profile1 . py 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 127 131 137 139 149 151 157 163 167 173 179 181 191 239 241 251 257 263 269 271 277 281 283 293 307 311 367 373 379 383 389 397 401 409 419 421 431 433 439 491 499 503 509 521 523 541 547 557 563 569 571 577 631 641 643 647 653 659 661 673 677 683 691 701 709 769 773 787 797 809 811 821 823 827 829 839 853 857 919 929 937 941 947 953 967 971 977 983 991 997 79023 function calls in 0.530 CPU seconds 79 193 313 443 587 719 859 83 89 97 197 199 317 331 449 457 593 599 727 733 863 877 101 211 337 461 601 739 881 103 223 347 463 607 743 883 107 227 349 467 613 751 887 109 229 353 479 617 757 907 Ordered by : standard name ncalls 1 1 78021 1 998 1 0 tottime 0.000 0.000 0.230 0.000 0.290 0.010 0.000 percall 0.000 0.000 0.000 0.000 0.000 0.010 cumtime 0.520 0.520 0.230 0.520 0.520 0.530 0.000 percall 0.520 0.520 0.000 0.520 0.001 0.530 filename : lineno ( function ) < string >:1(?) ex_profile1 . py :1(?) ex_profile1 . py :1( ismultiple ) ex_profile1 . py :10( main ) ex_profile1 . py :4( isprime ) profile :0( execfile ( ’ ex_profile1 . py ’) ) profile :0( profiler ) $ python -m profile ex_profile2 . py ... 3802 function calls in 0.040 CPU seconds Ordered by : standard name ncalls 1 1 1 2800 998 1 0 tottime 0.000 0.000 0.000 0.000 0.020 0.020 0.000 percall 0.000 0.000 0.000 0.000 0.000 0.020 cumtime 0.020 0.020 0.020 0.000 0.020 0.040 0.000 percall 0.020 0.020 0.020 0.000 0.000 0.040 filename : lineno ( function ) < string >:1(?) ex_profile2 . py :1(?) ex_profile2 . py :18( main ) ex_profile2 . py :3( ismultiple ) ex_profile2 . py :6( isprime ) profile :0( execfile ( ’ ex_profile2 . py ’) ) profile :0( profiler ) 113 233 359 487 619 761 911 Python profiler – Mais informação Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Manual de referência do módulo profile http://docs.python.org/lib/profile.html IDEs – eric3 Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Escrito em Python. Integra ferramentas de: debugging unit testing code coverage profiling IDEs – eric3 Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas IDEs – eric3 Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas IDEs – PyDev Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Plug-in para o eclipse (escrito em Java). Integra ferramentas de: debugging code coverage refactoring IDEs – PyDev Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas IDEs – PyDev Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas IDEs – Mais informação Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling eric3 Python IDE http://www.die-offenbachs.de/detlev/eric3.html PyDev Eclipse plugin http://pydev.sf.net/ Python profiler IDEs eric3 PyDev Outras ferramentas Integrated Development Environments – PythonInfo Wiki http://wiki.python.org/moin/IntegratedDevelopmentEnvironments Outras ferramentas Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Python debugger http://docs.python.org/lib/module-pdb.html Pylint – analisa estaticamente código python à procura de bugs ou código de má qualidade http://www.logilab.org/projects/pylint Ferramentas de teste para a linguagem Python José Fonseca Introdução Testes unitários doctest PyUnit Cobertura de código coverage.py Profiling Python profiler IDEs eric3 PyDev Outras ferramentas Questões?