SlideShare a Scribd company logo
1 of 18
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
TTeessttaannddoo ccoomm ppyy..tteesstt ee ttooxx 
DDaanniilloo ddee JJeessuuss ddaa SSiillvvaa BBeelllliinnii 
TTwwiitttteerr:: @@ddaanniilloobbeelllliinnii 
hhttttpp::////ppyytteesstt..oorrgg// 
hhttttppss::////ttooxx..rreeaaddtthheeddooccss..oorrgg// 
hhttttppss::////ggiitthhuubb..ccoomm//sscchhllaammaarr//ppyytteesstt--ccoovv 
hhttttpp::////nneeddbbaattcchheellddeerr..ccoomm//ccooddee//ccoovveerraaggee
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
AAssppeeccttooss ggeerraaiiss 
● AAmmbbooss ccrriiaaddooss ppoorr HHoollggeerr KKrreekkeell 
– OOrriiggiinnaallmmeennttee,, oo ppyy..tteesstt eerraa ppaarrttee ddee uummaa ccoolleettâânneeaa ““ppyy”” 
● OObbjjeettiivvoo cceennttrraall 
– AAuuttoommaattiizzaarr ((ee ppaaddrroonniizzaarr)) tteesstteess 
● TTeesstteess ccoomm 
– CCPPyytthhoonn 22..xx ((22..66++)) ee 33..xx 
– PPyyPPyy 
– PPooddee sseerr uussaaddoo ppaarraa tteessttaarr ccóóddiiggooss eemm oouuttrraass lliinngguuaaggeennss
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
CCrriiaaççããoo ddoo aammbbiieennttee ee iinnssttaallaaççããoo 
● AAddmmiittiinnddoo oo vviirrttuuaalleennvv iinnssttaallaaddoo ee aattuuaalliizzaaddoo ((aalléémm ddoo ppiipp)),, ccrriiee 
uumm ddiirreettóórriioo ““ppyyttuutt”” ccoomm oo ccoommaannddoo:: 
EEssttee sseerráá oo aammbbiieennttee ppaarraa aa rreeaalliizzaaççããoo ddooss tteesstteess,, aalléémm ddaa 
iinnssttaallaaççããoo ddoo ppyy..tteesstt ee ddoo ttooxx.. 
● AAttiivvee oo aammbbiieennttee ((aass lliinnhhaass ggaannhhaarrããoo uumm pprreeffiixxoo)):: 
● IInnssttaallee oo ppyy..tteesstt,, oo ppyytteesstt--ccoovv ee oo ttooxx:: 
● PPaarraa ddeessaattiivvaarr:: 
$$ vviirrttuuaalleennvv ppyyttuutt 
$$ .. ppyyttuutt//bbiinn//aaccttiivvaattee 
$$ ppiipp iinnssttaallll ttooxx ppyytteesstt ppyytteesstt--ccoovv 
$$ ddeeaaccttiivvaattee
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
PPrriimmeeiirrooss ppaassssooss 
● AArrqquuiivvoo tteesstt__iinncc..ppyy:: 
● RRooddaarr oo tteessttee:: 
● OO tteessttee ppaassssaa?? 
def incrementa(x): 
def incrementa(x): 
def test_incrementa_3(): 
– CCoorrrriijjaa oo ccóóddiiggoo 
return x - 1 
return x - 1 
def test_incrementa_3(): 
assert incrementa(3) == 4 
assert incrementa(3) == 4 
$$ ppyy..tteesstt 
Nota: os números 
à direita dos slides 
se referem a uma 
sugestão de 
organização das 
etapas do tutorial 
em diferentes 
diretórios ou 
commits 
01_01 
01_02
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
CCoolllleeccttiioonn ttiimmee 
CCoommoo oo ppyy..tteesstt eennccoonnttrraa ooss tteesstteess?? 
● CCoonnvveennççããoo ddee nnoommeess!! 
– PPrreeffiixxooss ““tteesstt__”” nnooss aarrqquuiivvooss ee ffuunnççõõeess//mmééttooddooss 
– PPrreeffiixxoo TTeesstt nnooss nnoommeess ddaass ccllaasssseess 
● TTeennttee oo eexxeemmpplloo aanntteerriioorr nnoovvaammeennttee,, mmaass mmaanntteennddoo 
oo aarrqquuiivvoo ccoomm oo nnoommee iinnccrreemmeennttaa..ppyy 
– OO qquuee aaccoonntteeccee?? 
– EE cchhaammaannddoo ccoomm oo nnoommee ddoo aarrqquuiivvoo ccoommoo ppaarrââmmeettrroo?? 
$$ ppyy..tteesstt iinnccrreemmeennttaa..ppyy 01_03 
Para organização estrutural em diretórios e outras 
sugestões/convenções, veja 
http://pytest.org/latest/goodpractises.html
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
FFaattoorriiaall 
● CCoomm aa ffuunnççããoo ffaattoorriiaall eemm uumm aarrqquuiivvoo ffaatt..ppyy ...... 
def fatorial(x): 
def fatorial(x): 
return 1 if n <= 1 else n * fatorial(n - 1) 
return 1 if n <= 1 else n * fatorial(n - 1) 
…… ffaaççaa rroottiinnaass ddee tteesstteess ((ffuunnççõõeess)) ppaarraa ppeelloo mmeennooss 
77 ddiiffeerreenntteess eennttrraaddaass vváálliiddaass eemm uumm aarrqquuiivvoo 
tteesstt__ffaatt..ppyy 
from fat import fatorial 
from fat import fatorial 
# Continuar ... 
# Continuar ... 
● RRooddaarr ccoomm:: $$ ppyy..tteesstt 
02_01
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
QQuuaannttiiddaaddee ddee tteesstteess ee tteesstteess 
ppaarraammeettrriizzaaddooss 
● IImmpplleemmeennttee uummaa vveerrssããoo aalltteerrnnaattiivvaa aaoo tteesstt__ffaatt..ppyy 
uuttiilliizzaannddoo aappeennaass uumm úúnniiccoo tteessttee ccoomm vváárriiooss ““aasssseerrtt”” 
– OO qquuee aaccoonntteeccee ccoomm aa ccoonnttaaggeemm ddooss tteesstteess? 
● IImmpplleemmeennttee oo tteesstt__ffaatt..ppyy uussaannddoo:: 
02_02 
02_03 
import pytest 
from fat import fatorial 
import pytest 
from fat import fatorial 
schema = "n", "out" 
table = [ # Pares (entrada "n", saída "out") 
schema = "n", "out" 
table = [ # Pares (entrada "n", saída "out") 
(0, 1), 
# ... complete com os demais pares 
(0, 1), 
# ... complete com os demais pares 
] 
@pytest.mark.parametrize(schema, table) 
def test_mapeia_entrada_saida(n, out): 
] 
@pytest.mark.parametrize(schema, table) 
def test_mapeia_entrada_saida(n, out): 
assert fatorial(n) == out 
assert fatorial(n) == out
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
PPeeqquueennaass ddiiccaass ssoobbrree oo uussoo ddee tteesstteess 
ppaarraammeettrriizzaaddooss 
● IItteerráávveeiiss eemm ggeerraall ccoommoo ttaabbeellaa ddee ddaaddooss,, ee..gg.. 
ttaabbllee == eennuummeerraattee(([[11,, 11,, 22,, 66,, 2244,, 112200,, 772200]])) 02_04 
● NNaa pprreesseennççaa ddee mmuuiittaass rroottiinnaass ddee tteesstteess sseennddoo 
ppaarraammeettrriizzaaddaass,, ppooddee--ssee ffaazzeerr …… 
pp == ppyytteesstt..mmaarrkk..ppaarraammeettrriizzee 
…… ppaarraa ddeeffiinniirr oo ddeeccoorraattoorr ““@@pp(())”” iinnddiiccaannddoo tteessttee 
ppaarraammeettrriizzaaddoo 
● SScchheemmaa ddee uumm úúnniiccoo vvaalloorr nnããoo pprreecciissaa sseerr uummaa ttuuppllaa 
● AAss mmeessmmaass ttaabbeellaass ppooddeemm sseerr uuttiilliizzaaddaass eemm ddiiffeerreenntteess 
tteesstteess ((ee..gg.. uussoo nnoo ppaatttteerrnn ssttrraatteeggyy,, mmúúllttiippllaass 
iimmpplleemmeennttaaççõõeess ddee uummaa mmeessmmaa ttaarreeffaa))
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
EExxcceeççããoo 
● MMooddiiffiiqquuee aa ffuunnççããoo ffaattoorriiaall ppaarraa llaannççaarr uummaa eexxcceeççããoo 
VVaalluueeEErrrroorr qquuaannddoo aa eennttrraaddaa ffoorr nneeggaattiivvaa.. 
if n < 0: 
if n < 0: 
raise ValueError("Use apenas inteiros positivos") 
raise ValueError("Use apenas inteiros positivos") 
● CCoommoo tteessttaarr iissssoo? 
– GGeerreenncciiaaddoorr ddee ccoonntteexxttoo!! 
with pytest.raises(ValueError): 
with pytest.raises(ValueError): 
# Fazer algo que deveria lançar um ValueError 
# Fazer algo que deveria lançar um ValueError 
– CCrriiee ppeelloo mmeennooss ddooiiss tteesstteess ccoonntteennddoo eessssee ggeerreenncciiaaddoorr ddee 
ccoonntteexxttoo,, uumm nnoo qquuaall aa eexxcceeççããoo ooccoorrrree ee oouuttrroo nnoo qquuaall aa 
eexxcceeççããoo nnããoo ooccoorrrree.. 
● AAllgguumm tteessttee ffaallhhoouu? 
02_05
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
Podemos usar um “xfail” (expected 
to fail) no primeiro teste de exceção 
realizado que sabíamos que 
falharia (um dos 2 testes do 02_05) 
inserindo o seguinte decorator na 
rotina de testes: 
SSkkiipp//xxffaaiill 
● HHáá tteesstteess qquuee ppooddeemm ffaazzeerr sseennttiiddoo eemm ssoommeennttee uumm 
ddooss aammbbiieenntteess ((ee..gg.. tteessttee qquuee ddeeppeennddee ddoo 
iitteerrttoooollss..aaccccuummuullaattee ddoo PPyytthhoonn 33)).. 
● CCoonnddiicciioonnaall 
– ppyytteesstt..mmaarrkk..sskkiippiiff 
– ppyytteesstt..mmaarrkk..xxffaaiill 
● IImmppeerraattiivvoo ((ccoommaannddooss)) 
– ppyytteesstt..sskkiipp 
– ppyytteesstt..xxffaaiill 
@@ppyytteesstt..mmaarrkk..xxffaaiill 
Extra!
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
TTeessttaannddoo aa mmeennssaaggeemm ddee eexxcceeççããoo 
● OO bbllooccoo wwiitthh aappeennaass tteessttaa ssee aa eexxcceeççããoo ooccoorrrreeuu.. 
PPoossssiivveellmmeennttee aa eexxcceeççããoo ppooddeerriiaa tteerr ooccoorrrriiddoo ccoomm uummaa 
mmeennssaaggeemm ddiiffeerreennttee ddaa ddeesseejjaaddaa ((ee..gg.. ppoorr eexxiissttiirr mmaaiiss ddee 
uummaa ffoorrmmaa ppaarraa oo vvaalloorr ddee eennttrraaddaa eessttaarr ffoorraa ddoo ddoommíínniioo ddee 
aapplliiccaabbiilliiddaaddee ddaa ffuunnççããoo)) 
● FFaaççaa uumm tteessttee uussaannddoo aa eennttrraaddaa ““22jj”” ((oo nnúúmmeerroo iimmaaggiinnáárriioo 22)),, 
aa qquuaall llaannççaa uumm TTyyppeeEErrrroorr.. VVeerriiffiiqquuee ssee aa mmeennssaaggeemm ccoonnttéémm 
aa ppaallaavvrraa ““ccoommpplleexx””.. 
02_07 
with pytest.raises(TypeError): 
with pytest.raises(TypeError): 
try: 
# Bloco que deveria lançar a exceção 
except TypeError as exc: 
assert "complex" in str(exc) 
raise # Propaga o TypeError 
try: 
# Bloco que deveria lançar a exceção 
except TypeError as exc: 
assert "complex" in str(exc) 
raise # Propaga o TypeError 02_06 
…… ee uussaannddoo oo ppyy..ccooddee..EExxcceeppttiioonnIInnffoo(()) ...... 
with pytest.raises(TypeError) as excinfo: 
with pytest.raises(TypeError) as excinfo: 
# Bloco que deveria lançar a exceção 
# Bloco que deveria lançar a exceção 
assert "complex" in str(excinfo.value) 
assert "complex" in str(excinfo.value) 
Dica: Troque o nome 
“complex” por outro 
que não existe na 
string, a fim de “testar 
o teste” e assegurar 
de que ele realmente 
está verificando essa 
informação.
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
DDoocctteessttss ((tteesstteess ddee ddooccuummeennttaaççããoo)) 
● Coommppaarraa tteexxttoo 
● IImmpplleemmeennttee aa 
ffuunnççããoo aaoo llaaddoo eemm 
uumm aarrqquuiivvoo nnoottaa..ppyy 
● Chhaammee oo ppyy..tteesstt 
ccoomm:: 
● Coollooqquuee uumm tteessttee 
ddee ddooccuummeennttaaççããoo 
ccoomm uummaa ssttrriinngg 
ccoommoo eennttrraaddaa 
def nome_nota(pitch): 
def nome_nota(pitch): 
""" 
Encontra o nome da nota dado o pitch 
MIDI (dado em semitons) caso 
esteja na pentatonica de Am. 
>>> nome_nota(69) # A4 (La central) 
'A' 
>>> nome_nota(70) # Bb4 
Traceback (most recent call last): 
""" 
Encontra o nome da nota dado o pitch 
MIDI (dado em semitons) caso 
esteja na pentatonica de Am. 
>>> nome_nota(69) # A4 (La central) 
'A' 
>>> nome_nota(70) # Bb4 
Traceback (most recent call last): 
... 
... 
ValueError: Fora da escala! 
""" 
ans = [] 
if pitch % 12 == 0: 
ValueError: Fora da escala! 
""" 
ans = [] 
if pitch % 12 == 0: 
return "C" 
return "C" 
if pitch % 12 == 2: 
if pitch % 12 == 2: 
return "D" 
return "D" 
if pitch % 12 == 4: 
if pitch % 12 == 4: 
return "E" 
return "E" 
if pitch % 12 == 7: 
if pitch % 12 == 7: 
return "G" 
return "G" 
if pitch % 12 == 9: 
if pitch % 12 == 9: 
return "A" 
return "A" 
raise ValueError("Fora da escala!") 
raise ValueError("Fora da escala!") 
03_01 
$$ ppyy..tteesstt ----ddoocctteesstt--mmoodduulleess 
… (Ellipsis): 
Parte do doctest 
para “casar com 
o que vier” 
03_02
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
Coobbeerrttuurraa ddee ccóóddiiggoo 
● Crriiee uumm ttooxx..iinnii ccoonntteennddoo 
[pytest] 
addopts = --doctest-modules 
[pytest] 
addopts = --doctest-modules 
Tente também com “html” no 
lugar de “term-missing” 
--cov-config tox.ini 
--cov-report term-missing 
--cov nota 
--cov-config tox.ini 
--cov-report term-missing 
--cov nota 
AAggoorraa nnããoo éé mmaaiiss nneecceessssáárriioo ddiiggiittaarr ppaarrââmmeettrrooss aaoo cchhaammaarr oo 
ppyy..tteesstt ((eexxcceettoo ppaarrââmmeettrrooss ccoommpplleemmeennttaarreess)) 
● AA lliinnhhaa ““ccoovv--ccoonnffiigg”” sseerrvvee ppaarraa uunniiffiiccaarr oo ttooxx..iinnii ccoommoo aarrqquuiivvoo 
úúnniiccoo ddee ccoonnffiigguurraaççããoo ddoo ttooxx ((aaiinnddaa nnããoo uuttiilliizzaaddoo)),, ppyy..tteesstt ee 
ppyytteesstt--ccoovv.. PPaarraa ttoorrnnaarr ttaall lliinnhhaa úúttiill,, aavvaalliiee aa ccoobbeerrttuurraa ddee 
ccóóddiiggoo ccoomm bbrraanncchhiinngg ccoollooccaannddoo iissttoo ttaammbbéémm nnoo ttooxx..iinnii 
((ccoonnffiigguurraa oo ppyytteesstt--ccoovv)):: 
[run] 
branch = True 
[run] 
branch = True 
● Coonnsseegguueemm ccoommpplleettaarr ddoocctteessttss ppaarraa cchheeggaarr aa 110000%% ddee 
ccoobbeerrttuurraa?? 03_03
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
OOrrááccuullooss ee tteesstteess aalleeaattóórriiooss 
Extra! 
● UUssoo aaoo iimmpplleemmeennttaarr uumm aallggoorriittmmoo ccoomm iimmpplleemmeennttaaççããoo ddee 
rreeffeerrêênncciiaa pprroonnttaa ppaarraa ppeelloo mmeennooss ppaarrttee ddoo ddoommíínniioo.. 
– NNoo ccaassoo mmaaiiss ssiimmpplleess,, sseemm oorrááccuullooss,, tteesstteess aalleeaattóórriiooss 
rreepprreesseennttaamm aa rreessiissttêênncciiaa aa ““ffaallhhaa ddee sseeggmmeennttaaççããoo”” oouu ccooiissaass 
ssiimmiillaarreess,, aallggoo qquuee nnããoo ffaarreemmooss nneessttee mmiinniiccuurrssoo.. 
– Coomm oorrááccuullooss,, ppooddeemmooss ssiimmpplleessmmeennttee uuttiilliizzaarr uummaa 
iimmpplleemmeennttaaççããoo ppaarraa tteessttaarr oouuttrraa,, ccrriiaannddoo tteesstteess mmaassssiivvaammeennttee.. 
● OO qquuee ooccoorrrree qquuaannddoo ssee uuttiilliizzaa oo ddeeccoorraattoorr 
ppyytteesstt..mmaarrkk..ppaarraammeettrriizzee mmaaiiss ddee uummaa vveezz?? 
● IImmpplleemmeennttee uumm aallggoorriittmmoo ((qquuaallqquueerr)) ppaarraa oorrddeennaaççããoo ddee 
lliissttaass uuttiilliizzaannddoo oo bbuuiilltt--iinn ““ssoorrtteedd”” ccoommoo oorrááccuulloo ppaarraa ooss 
tteesstteess eemm uumm úúnniiccoo tteessttee ppaarraammeettrriizzaaddoo.. 04_01
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
TTooxx 
● GGeerreenncciiaa mmúúllttiippllooss aammbbiieenntteess vviirrttuuaaiiss,, ppaarraa aauuttoommaattiizzaarr 
ooss tteesstteess eemm ttooddooss ooss aammbbiieenntteess 
● EExxiiggêênncciiaass:: 
– UUmm aarrqquuiivvoo sseettuupp..ppyy ddoo pprroojjeettoo ((iinnssttaallaaççããoo//ccoonnffiigguurraaççããoo ddoo 
““ppaacckkaaggee””)) 
– UUmm aarrqquuiivvoo ttooxx..iinnii ((ccoonnffiigguurraaççããoo ddoo ttooxx ee ppyy..tteesstt)) 
● VVaammooss ffaazzeerr aallgguumm ddooss ““pprroojjeettooss”” jjáá ccrriiaaddooss ffuunncciioonnaarr 
ttaannttoo nnoo PPyytthhoonn 22 ccoommoo nnoo PPyytthhoonn 33 ((eexxcceettoo oo qquuee 
uuttiilliizzaa ddoocctteessttss)).. 
from setuptools import setup 
setup(name="pytut") 
from setuptools import setup 
setup(name="pytut") 
Este setup.py é MÍNIMO. 
O nome é usado pelo tox para 
criar um egg 
Exemplo de parte do tox.ini 
que configura o tox. 
[tox] 
envlist = py27, py34 
[tox] 
envlist = py27, py34 
[testenv] 
deps = pytest 
commands = py.test 
[testenv] 
deps = pytest 
commands = py.test 
$$ ttooxx 
0X_0Y
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
PPoonnttoo fflluuttuuaannttee 
● CCoommppaarraarr ppoorr aapprrooxxiimmaaççããoo 
– VVaalloorr aabbssoolluuttoo ddaa ddiiffeerreennççaa 
– EErrrroo ppeerrcceennttuuaall//rreellaattiivvoo ((nnããoo--ssiimmééttrriiccoo)) 
– TToolleerrâânncciiaa eemm nnúúmmeerroo ddee bbiittss ddee mmaannttiissssaa 
● HHáá iimmpplleemmeennttaaççõõeess pprroonnttaass 
– nnuummppyy..iisscclloossee,, nnuummppyy..aallllcclloossee 
– aauuddiioollaazzyy..aallmmoosstt__eeqq 
– uunniitttteesstt..TTeessttCCaassee..aasssseerrttAAllmmoossttEEqquuaall 
● UUssoo ddee aarrrreeddoonnddaammeennttooss eexxppllíícciittooss 
Extra!
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
MMiisscceellâânneeaa 
$ py.test --help 
usage: py.test [options] [file_or_dir] [file_or_dir] [...] 
... 
$ py.test --help 
usage: py.test [options] [file_or_dir] [file_or_dir] [...] 
... 
● VVeejjaamm aa aajjuuddaa ddoo ppyy..tteesstt!! 
– TTooddooss ooss ppaarrââmmeettrrooss ssããoo ooppcciioonnaaiiss,, mmaass qquuaaiiss ooss 
ppaarrââmmeettrrooss?? 
● ÉÉ ppoossssíívveell sseelleecciioonnaarr ssoommeennttee aallgguunnss tteesstteess ppaarraa 
sseerreemm rrooddaaddooss.. 
– SSeeppaarraaççããoo ppoorr aarrqquuiivvoo,, ttrriivviiaall 
– UUsseemm ““--kk”” ppaarraa sseelleecciioonnaarr uummaa ppaarrttee ddaa ssuuííttee ddee tteesstteess 
((bbaasseeaaddoo nnooss nnoommeess ddooss tteesstteess)) 
$$ ppyy..tteesstt ----ccoolllleecctt--oonnllyy
py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii 
@@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG 
Perguntas ? FFIIMM!! 
OObbrriiggaaddoo!! 
hhttttpp::////ppyytteesstt..oorrgg// 
hhttttppss::////ttooxx..rreeaaddtthheeddooccss..oorrgg// 
hhttttppss::////ggiitthhuubb..ccoomm//sscchhllaammaarr//ppyytteesstt--ccoovv 
hhttttpp::////nneeddbbaattcchheellddeerr..ccoomm//ccooddee//ccoovveerraaggee

More Related Content

More from Danilo J. S. Bellini

(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)Danilo J. S. Bellini
 
(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!Danilo J. S. Bellini
 
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)Danilo J. S. Bellini
 
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!Danilo J. S. Bellini
 
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...Danilo J. S. Bellini
 
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)Danilo J. S. Bellini
 
(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em PythonDanilo J. S. Bellini
 
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...Danilo J. S. Bellini
 
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazyDanilo J. S. Bellini
 
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com PythonDanilo J. S. Bellini
 
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3Danilo J. S. Bellini
 
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojosDanilo J. S. Bellini
 
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3Danilo J. S. Bellini
 
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...Danilo J. S. Bellini
 

More from Danilo J. S. Bellini (18)

(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
(2017-08-12) [GruPy-SP] AudioLazy no GruPy! (+LV2)
 
(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!(2017-07-22) [TDC] Audiolazy em 2017!
(2017-07-22) [TDC] Audiolazy em 2017!
 
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
(2017-05-27) [Grupy-SP] Polígonos, pontos e outras geometrias no Shapely (GIS)
 
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
(2014-08-09) [TDC] AudioLazy 0.6 will robotize you!
 
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
(2014-05-24) [Taubaté Perl Mongers] AudioLazy Python DSP (Digital Signal Proc...
 
(2014-04-16) [Garoa HC] Strategy
(2014-04-16) [Garoa HC] Strategy(2014-04-16) [Garoa HC] Strategy
(2014-04-16) [Garoa HC] Strategy
 
(2013-12-18) [Garoa HC] AudioLazy
(2013-12-18) [Garoa HC] AudioLazy(2013-12-18) [Garoa HC] AudioLazy
(2013-12-18) [Garoa HC] AudioLazy
 
(2014-03-26) [7masters] AudioLazy
(2014-03-26) [7masters] AudioLazy(2014-03-26) [7masters] AudioLazy
(2014-03-26) [7masters] AudioLazy
 
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
(2013-11-29) [RuPy] AudioLazy Python DSP (Digital Signal Processing)
 
(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python(2013-10-16) [LatinoWare] Processamento de sinais em Python
(2013-10-16) [LatinoWare] Processamento de sinais em Python
 
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
(2013-10-03) [PythonBrasil] AudioLazy, processamento de sinais para música, j...
 
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
(2013-09-30) [PythonBrasil] Síntese em tempo real com a AudioLazy
 
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
(2013-10-17) [LatinoWare] Automatizando o GIMP com Python
 
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
(2013-10-02) [PythonBrasil] Compatibilidade entre Python 2 e 3
 
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
(2013-07-05) [fisl] Semáforo Gráfico dose para TDD em dojos
 
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
(2013-07-05) [fisl] Compatibilidade entre Python 2 e 3
 
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
(2013-05-20) [DevInSampa] AudioLazy - DSP expressivo e em tempo real para o P...
 
(2013-05-03) AudioLazy - Slides
(2013-05-03) AudioLazy - Slides(2013-05-03) AudioLazy - Slides
(2013-05-03) AudioLazy - Slides
 

(2014-10-27) [SETI-UFLA-MG] Testando com py.test e tox

  • 1. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG TTeessttaannddoo ccoomm ppyy..tteesstt ee ttooxx DDaanniilloo ddee JJeessuuss ddaa SSiillvvaa BBeelllliinnii TTwwiitttteerr:: @@ddaanniilloobbeelllliinnii hhttttpp::////ppyytteesstt..oorrgg// hhttttppss::////ttooxx..rreeaaddtthheeddooccss..oorrgg// hhttttppss::////ggiitthhuubb..ccoomm//sscchhllaammaarr//ppyytteesstt--ccoovv hhttttpp::////nneeddbbaattcchheellddeerr..ccoomm//ccooddee//ccoovveerraaggee
  • 2. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG AAssppeeccttooss ggeerraaiiss ● AAmmbbooss ccrriiaaddooss ppoorr HHoollggeerr KKrreekkeell – OOrriiggiinnaallmmeennttee,, oo ppyy..tteesstt eerraa ppaarrttee ddee uummaa ccoolleettâânneeaa ““ppyy”” ● OObbjjeettiivvoo cceennttrraall – AAuuttoommaattiizzaarr ((ee ppaaddrroonniizzaarr)) tteesstteess ● TTeesstteess ccoomm – CCPPyytthhoonn 22..xx ((22..66++)) ee 33..xx – PPyyPPyy – PPooddee sseerr uussaaddoo ppaarraa tteessttaarr ccóóddiiggooss eemm oouuttrraass lliinngguuaaggeennss
  • 3. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG CCrriiaaççããoo ddoo aammbbiieennttee ee iinnssttaallaaççããoo ● AAddmmiittiinnddoo oo vviirrttuuaalleennvv iinnssttaallaaddoo ee aattuuaalliizzaaddoo ((aalléémm ddoo ppiipp)),, ccrriiee uumm ddiirreettóórriioo ““ppyyttuutt”” ccoomm oo ccoommaannddoo:: EEssttee sseerráá oo aammbbiieennttee ppaarraa aa rreeaalliizzaaççããoo ddooss tteesstteess,, aalléémm ddaa iinnssttaallaaççããoo ddoo ppyy..tteesstt ee ddoo ttooxx.. ● AAttiivvee oo aammbbiieennttee ((aass lliinnhhaass ggaannhhaarrããoo uumm pprreeffiixxoo)):: ● IInnssttaallee oo ppyy..tteesstt,, oo ppyytteesstt--ccoovv ee oo ttooxx:: ● PPaarraa ddeessaattiivvaarr:: $$ vviirrttuuaalleennvv ppyyttuutt $$ .. ppyyttuutt//bbiinn//aaccttiivvaattee $$ ppiipp iinnssttaallll ttooxx ppyytteesstt ppyytteesstt--ccoovv $$ ddeeaaccttiivvaattee
  • 4. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG PPrriimmeeiirrooss ppaassssooss ● AArrqquuiivvoo tteesstt__iinncc..ppyy:: ● RRooddaarr oo tteessttee:: ● OO tteessttee ppaassssaa?? def incrementa(x): def incrementa(x): def test_incrementa_3(): – CCoorrrriijjaa oo ccóóddiiggoo return x - 1 return x - 1 def test_incrementa_3(): assert incrementa(3) == 4 assert incrementa(3) == 4 $$ ppyy..tteesstt Nota: os números à direita dos slides se referem a uma sugestão de organização das etapas do tutorial em diferentes diretórios ou commits 01_01 01_02
  • 5. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG CCoolllleeccttiioonn ttiimmee CCoommoo oo ppyy..tteesstt eennccoonnttrraa ooss tteesstteess?? ● CCoonnvveennççããoo ddee nnoommeess!! – PPrreeffiixxooss ““tteesstt__”” nnooss aarrqquuiivvooss ee ffuunnççõõeess//mmééttooddooss – PPrreeffiixxoo TTeesstt nnooss nnoommeess ddaass ccllaasssseess ● TTeennttee oo eexxeemmpplloo aanntteerriioorr nnoovvaammeennttee,, mmaass mmaanntteennddoo oo aarrqquuiivvoo ccoomm oo nnoommee iinnccrreemmeennttaa..ppyy – OO qquuee aaccoonntteeccee?? – EE cchhaammaannddoo ccoomm oo nnoommee ddoo aarrqquuiivvoo ccoommoo ppaarrââmmeettrroo?? $$ ppyy..tteesstt iinnccrreemmeennttaa..ppyy 01_03 Para organização estrutural em diretórios e outras sugestões/convenções, veja http://pytest.org/latest/goodpractises.html
  • 6. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG FFaattoorriiaall ● CCoomm aa ffuunnççããoo ffaattoorriiaall eemm uumm aarrqquuiivvoo ffaatt..ppyy ...... def fatorial(x): def fatorial(x): return 1 if n <= 1 else n * fatorial(n - 1) return 1 if n <= 1 else n * fatorial(n - 1) …… ffaaççaa rroottiinnaass ddee tteesstteess ((ffuunnççõõeess)) ppaarraa ppeelloo mmeennooss 77 ddiiffeerreenntteess eennttrraaddaass vváálliiddaass eemm uumm aarrqquuiivvoo tteesstt__ffaatt..ppyy from fat import fatorial from fat import fatorial # Continuar ... # Continuar ... ● RRooddaarr ccoomm:: $$ ppyy..tteesstt 02_01
  • 7. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG QQuuaannttiiddaaddee ddee tteesstteess ee tteesstteess ppaarraammeettrriizzaaddooss ● IImmpplleemmeennttee uummaa vveerrssããoo aalltteerrnnaattiivvaa aaoo tteesstt__ffaatt..ppyy uuttiilliizzaannddoo aappeennaass uumm úúnniiccoo tteessttee ccoomm vváárriiooss ““aasssseerrtt”” – OO qquuee aaccoonntteeccee ccoomm aa ccoonnttaaggeemm ddooss tteesstteess? ● IImmpplleemmeennttee oo tteesstt__ffaatt..ppyy uussaannddoo:: 02_02 02_03 import pytest from fat import fatorial import pytest from fat import fatorial schema = "n", "out" table = [ # Pares (entrada "n", saída "out") schema = "n", "out" table = [ # Pares (entrada "n", saída "out") (0, 1), # ... complete com os demais pares (0, 1), # ... complete com os demais pares ] @pytest.mark.parametrize(schema, table) def test_mapeia_entrada_saida(n, out): ] @pytest.mark.parametrize(schema, table) def test_mapeia_entrada_saida(n, out): assert fatorial(n) == out assert fatorial(n) == out
  • 8. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG PPeeqquueennaass ddiiccaass ssoobbrree oo uussoo ddee tteesstteess ppaarraammeettrriizzaaddooss ● IItteerráávveeiiss eemm ggeerraall ccoommoo ttaabbeellaa ddee ddaaddooss,, ee..gg.. ttaabbllee == eennuummeerraattee(([[11,, 11,, 22,, 66,, 2244,, 112200,, 772200]])) 02_04 ● NNaa pprreesseennççaa ddee mmuuiittaass rroottiinnaass ddee tteesstteess sseennddoo ppaarraammeettrriizzaaddaass,, ppooddee--ssee ffaazzeerr …… pp == ppyytteesstt..mmaarrkk..ppaarraammeettrriizzee …… ppaarraa ddeeffiinniirr oo ddeeccoorraattoorr ““@@pp(())”” iinnddiiccaannddoo tteessttee ppaarraammeettrriizzaaddoo ● SScchheemmaa ddee uumm úúnniiccoo vvaalloorr nnããoo pprreecciissaa sseerr uummaa ttuuppllaa ● AAss mmeessmmaass ttaabbeellaass ppooddeemm sseerr uuttiilliizzaaddaass eemm ddiiffeerreenntteess tteesstteess ((ee..gg.. uussoo nnoo ppaatttteerrnn ssttrraatteeggyy,, mmúúllttiippllaass iimmpplleemmeennttaaççõõeess ddee uummaa mmeessmmaa ttaarreeffaa))
  • 9. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG EExxcceeççããoo ● MMooddiiffiiqquuee aa ffuunnççããoo ffaattoorriiaall ppaarraa llaannççaarr uummaa eexxcceeççããoo VVaalluueeEErrrroorr qquuaannddoo aa eennttrraaddaa ffoorr nneeggaattiivvaa.. if n < 0: if n < 0: raise ValueError("Use apenas inteiros positivos") raise ValueError("Use apenas inteiros positivos") ● CCoommoo tteessttaarr iissssoo? – GGeerreenncciiaaddoorr ddee ccoonntteexxttoo!! with pytest.raises(ValueError): with pytest.raises(ValueError): # Fazer algo que deveria lançar um ValueError # Fazer algo que deveria lançar um ValueError – CCrriiee ppeelloo mmeennooss ddooiiss tteesstteess ccoonntteennddoo eessssee ggeerreenncciiaaddoorr ddee ccoonntteexxttoo,, uumm nnoo qquuaall aa eexxcceeççããoo ooccoorrrree ee oouuttrroo nnoo qquuaall aa eexxcceeççããoo nnããoo ooccoorrrree.. ● AAllgguumm tteessttee ffaallhhoouu? 02_05
  • 10. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG Podemos usar um “xfail” (expected to fail) no primeiro teste de exceção realizado que sabíamos que falharia (um dos 2 testes do 02_05) inserindo o seguinte decorator na rotina de testes: SSkkiipp//xxffaaiill ● HHáá tteesstteess qquuee ppooddeemm ffaazzeerr sseennttiiddoo eemm ssoommeennttee uumm ddooss aammbbiieenntteess ((ee..gg.. tteessttee qquuee ddeeppeennddee ddoo iitteerrttoooollss..aaccccuummuullaattee ddoo PPyytthhoonn 33)).. ● CCoonnddiicciioonnaall – ppyytteesstt..mmaarrkk..sskkiippiiff – ppyytteesstt..mmaarrkk..xxffaaiill ● IImmppeerraattiivvoo ((ccoommaannddooss)) – ppyytteesstt..sskkiipp – ppyytteesstt..xxffaaiill @@ppyytteesstt..mmaarrkk..xxffaaiill Extra!
  • 11. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG TTeessttaannddoo aa mmeennssaaggeemm ddee eexxcceeççããoo ● OO bbllooccoo wwiitthh aappeennaass tteessttaa ssee aa eexxcceeççããoo ooccoorrrreeuu.. PPoossssiivveellmmeennttee aa eexxcceeççããoo ppooddeerriiaa tteerr ooccoorrrriiddoo ccoomm uummaa mmeennssaaggeemm ddiiffeerreennttee ddaa ddeesseejjaaddaa ((ee..gg.. ppoorr eexxiissttiirr mmaaiiss ddee uummaa ffoorrmmaa ppaarraa oo vvaalloorr ddee eennttrraaddaa eessttaarr ffoorraa ddoo ddoommíínniioo ddee aapplliiccaabbiilliiddaaddee ddaa ffuunnççããoo)) ● FFaaççaa uumm tteessttee uussaannddoo aa eennttrraaddaa ““22jj”” ((oo nnúúmmeerroo iimmaaggiinnáárriioo 22)),, aa qquuaall llaannççaa uumm TTyyppeeEErrrroorr.. VVeerriiffiiqquuee ssee aa mmeennssaaggeemm ccoonnttéémm aa ppaallaavvrraa ““ccoommpplleexx””.. 02_07 with pytest.raises(TypeError): with pytest.raises(TypeError): try: # Bloco que deveria lançar a exceção except TypeError as exc: assert "complex" in str(exc) raise # Propaga o TypeError try: # Bloco que deveria lançar a exceção except TypeError as exc: assert "complex" in str(exc) raise # Propaga o TypeError 02_06 …… ee uussaannddoo oo ppyy..ccooddee..EExxcceeppttiioonnIInnffoo(()) ...... with pytest.raises(TypeError) as excinfo: with pytest.raises(TypeError) as excinfo: # Bloco que deveria lançar a exceção # Bloco que deveria lançar a exceção assert "complex" in str(excinfo.value) assert "complex" in str(excinfo.value) Dica: Troque o nome “complex” por outro que não existe na string, a fim de “testar o teste” e assegurar de que ele realmente está verificando essa informação.
  • 12. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG DDoocctteessttss ((tteesstteess ddee ddooccuummeennttaaççããoo)) ● Coommppaarraa tteexxttoo ● IImmpplleemmeennttee aa ffuunnççããoo aaoo llaaddoo eemm uumm aarrqquuiivvoo nnoottaa..ppyy ● Chhaammee oo ppyy..tteesstt ccoomm:: ● Coollooqquuee uumm tteessttee ddee ddooccuummeennttaaççããoo ccoomm uummaa ssttrriinngg ccoommoo eennttrraaddaa def nome_nota(pitch): def nome_nota(pitch): """ Encontra o nome da nota dado o pitch MIDI (dado em semitons) caso esteja na pentatonica de Am. >>> nome_nota(69) # A4 (La central) 'A' >>> nome_nota(70) # Bb4 Traceback (most recent call last): """ Encontra o nome da nota dado o pitch MIDI (dado em semitons) caso esteja na pentatonica de Am. >>> nome_nota(69) # A4 (La central) 'A' >>> nome_nota(70) # Bb4 Traceback (most recent call last): ... ... ValueError: Fora da escala! """ ans = [] if pitch % 12 == 0: ValueError: Fora da escala! """ ans = [] if pitch % 12 == 0: return "C" return "C" if pitch % 12 == 2: if pitch % 12 == 2: return "D" return "D" if pitch % 12 == 4: if pitch % 12 == 4: return "E" return "E" if pitch % 12 == 7: if pitch % 12 == 7: return "G" return "G" if pitch % 12 == 9: if pitch % 12 == 9: return "A" return "A" raise ValueError("Fora da escala!") raise ValueError("Fora da escala!") 03_01 $$ ppyy..tteesstt ----ddoocctteesstt--mmoodduulleess … (Ellipsis): Parte do doctest para “casar com o que vier” 03_02
  • 13. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG Coobbeerrttuurraa ddee ccóóddiiggoo ● Crriiee uumm ttooxx..iinnii ccoonntteennddoo [pytest] addopts = --doctest-modules [pytest] addopts = --doctest-modules Tente também com “html” no lugar de “term-missing” --cov-config tox.ini --cov-report term-missing --cov nota --cov-config tox.ini --cov-report term-missing --cov nota AAggoorraa nnããoo éé mmaaiiss nneecceessssáárriioo ddiiggiittaarr ppaarrââmmeettrrooss aaoo cchhaammaarr oo ppyy..tteesstt ((eexxcceettoo ppaarrââmmeettrrooss ccoommpplleemmeennttaarreess)) ● AA lliinnhhaa ““ccoovv--ccoonnffiigg”” sseerrvvee ppaarraa uunniiffiiccaarr oo ttooxx..iinnii ccoommoo aarrqquuiivvoo úúnniiccoo ddee ccoonnffiigguurraaççããoo ddoo ttooxx ((aaiinnddaa nnããoo uuttiilliizzaaddoo)),, ppyy..tteesstt ee ppyytteesstt--ccoovv.. PPaarraa ttoorrnnaarr ttaall lliinnhhaa úúttiill,, aavvaalliiee aa ccoobbeerrttuurraa ddee ccóóddiiggoo ccoomm bbrraanncchhiinngg ccoollooccaannddoo iissttoo ttaammbbéémm nnoo ttooxx..iinnii ((ccoonnffiigguurraa oo ppyytteesstt--ccoovv)):: [run] branch = True [run] branch = True ● Coonnsseegguueemm ccoommpplleettaarr ddoocctteessttss ppaarraa cchheeggaarr aa 110000%% ddee ccoobbeerrttuurraa?? 03_03
  • 14. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG OOrrááccuullooss ee tteesstteess aalleeaattóórriiooss Extra! ● UUssoo aaoo iimmpplleemmeennttaarr uumm aallggoorriittmmoo ccoomm iimmpplleemmeennttaaççããoo ddee rreeffeerrêênncciiaa pprroonnttaa ppaarraa ppeelloo mmeennooss ppaarrttee ddoo ddoommíínniioo.. – NNoo ccaassoo mmaaiiss ssiimmpplleess,, sseemm oorrááccuullooss,, tteesstteess aalleeaattóórriiooss rreepprreesseennttaamm aa rreessiissttêênncciiaa aa ““ffaallhhaa ddee sseeggmmeennttaaççããoo”” oouu ccooiissaass ssiimmiillaarreess,, aallggoo qquuee nnããoo ffaarreemmooss nneessttee mmiinniiccuurrssoo.. – Coomm oorrááccuullooss,, ppooddeemmooss ssiimmpplleessmmeennttee uuttiilliizzaarr uummaa iimmpplleemmeennttaaççããoo ppaarraa tteessttaarr oouuttrraa,, ccrriiaannddoo tteesstteess mmaassssiivvaammeennttee.. ● OO qquuee ooccoorrrree qquuaannddoo ssee uuttiilliizzaa oo ddeeccoorraattoorr ppyytteesstt..mmaarrkk..ppaarraammeettrriizzee mmaaiiss ddee uummaa vveezz?? ● IImmpplleemmeennttee uumm aallggoorriittmmoo ((qquuaallqquueerr)) ppaarraa oorrddeennaaççããoo ddee lliissttaass uuttiilliizzaannddoo oo bbuuiilltt--iinn ““ssoorrtteedd”” ccoommoo oorrááccuulloo ppaarraa ooss tteesstteess eemm uumm úúnniiccoo tteessttee ppaarraammeettrriizzaaddoo.. 04_01
  • 15. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG TTooxx ● GGeerreenncciiaa mmúúllttiippllooss aammbbiieenntteess vviirrttuuaaiiss,, ppaarraa aauuttoommaattiizzaarr ooss tteesstteess eemm ttooddooss ooss aammbbiieenntteess ● EExxiiggêênncciiaass:: – UUmm aarrqquuiivvoo sseettuupp..ppyy ddoo pprroojjeettoo ((iinnssttaallaaççããoo//ccoonnffiigguurraaççããoo ddoo ““ppaacckkaaggee””)) – UUmm aarrqquuiivvoo ttooxx..iinnii ((ccoonnffiigguurraaççããoo ddoo ttooxx ee ppyy..tteesstt)) ● VVaammooss ffaazzeerr aallgguumm ddooss ““pprroojjeettooss”” jjáá ccrriiaaddooss ffuunncciioonnaarr ttaannttoo nnoo PPyytthhoonn 22 ccoommoo nnoo PPyytthhoonn 33 ((eexxcceettoo oo qquuee uuttiilliizzaa ddoocctteessttss)).. from setuptools import setup setup(name="pytut") from setuptools import setup setup(name="pytut") Este setup.py é MÍNIMO. O nome é usado pelo tox para criar um egg Exemplo de parte do tox.ini que configura o tox. [tox] envlist = py27, py34 [tox] envlist = py27, py34 [testenv] deps = pytest commands = py.test [testenv] deps = pytest commands = py.test $$ ttooxx 0X_0Y
  • 16. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG PPoonnttoo fflluuttuuaannttee ● CCoommppaarraarr ppoorr aapprrooxxiimmaaççããoo – VVaalloorr aabbssoolluuttoo ddaa ddiiffeerreennççaa – EErrrroo ppeerrcceennttuuaall//rreellaattiivvoo ((nnããoo--ssiimmééttrriiccoo)) – TToolleerrâânncciiaa eemm nnúúmmeerroo ddee bbiittss ddee mmaannttiissssaa ● HHáá iimmpplleemmeennttaaççõõeess pprroonnttaass – nnuummppyy..iisscclloossee,, nnuummppyy..aallllcclloossee – aauuddiioollaazzyy..aallmmoosstt__eeqq – uunniitttteesstt..TTeessttCCaassee..aasssseerrttAAllmmoossttEEqquuaall ● UUssoo ddee aarrrreeddoonnddaammeennttooss eexxppllíícciittooss Extra!
  • 17. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG MMiisscceellâânneeaa $ py.test --help usage: py.test [options] [file_or_dir] [file_or_dir] [...] ... $ py.test --help usage: py.test [options] [file_or_dir] [file_or_dir] [...] ... ● VVeejjaamm aa aajjuuddaa ddoo ppyy..tteesstt!! – TTooddooss ooss ppaarrââmmeettrrooss ssããoo ooppcciioonnaaiiss,, mmaass qquuaaiiss ooss ppaarrââmmeettrrooss?? ● ÉÉ ppoossssíívveell sseelleecciioonnaarr ssoommeennttee aallgguunnss tteesstteess ppaarraa sseerreemm rrooddaaddooss.. – SSeeppaarraaççããoo ppoorr aarrqquuiivvoo,, ttrriivviiaall – UUsseemm ““--kk”” ppaarraa sseelleecciioonnaarr uummaa ppaarrttee ddaa ssuuííttee ddee tteesstteess ((bbaasseeaaddoo nnooss nnoommeess ddooss tteesstteess)) $$ ppyy..tteesstt ----ccoolllleecctt--oonnllyy
  • 18. py Testando com py..tteesstt ee ttooxx –– DDaanniilloo JJ.. SS.. BBeelllliinnii @@ddaanniilloobbeelllliinnii –– SSEETTII // UUFFLLAA –– 22001144--1100--2277 –– LLaavvrraass // MMGG Perguntas ? FFIIMM!! OObbrriiggaaddoo!! hhttttpp::////ppyytteesstt..oorrgg// hhttttppss::////ttooxx..rreeaaddtthheeddooccss..oorrgg// hhttttppss::////ggiitthhuubb..ccoomm//sscchhllaammaarr//ppyytteesstt--ccoovv hhttttpp::////nneeddbbaattcchheellddeerr..ccoomm//ccooddee//ccoovveerraaggee