Miten Suorittaa Yksikkö Testit Python Ilman kärsivällisyyttänne
Useammin kuin ei, meidän ohjelmisto kirjoittaa suoraan vuorovaikutuksessa, mitä voisi merkitä kuin ”likainen” palvelut. Maallikon termein: palvelut, jotka ovat välttämättömiä meidän sovellus, mutta joiden yhteisvaikutuksia ei ole tarkoitettu, mutta ei-toivottuja sivuvaikutuksia—se on, – toivottuja yhteydessä itsenäisen koeajo.,
esimerkiksi: ehkä me kirjoitamme sosiaaliseen app ja haluat testata uuden ’Post Facebook ominaisuus, mutta eivät halua lähettää Facebook joka kerta, kun olemme ajaa meidän testi suite.
Python unittest
kirjasto sisältää subpackage nimeltä unittest.mock
—tai jos sinun julistaa, että se riippuvuus, yksinkertaisesti mock
—joka tarjoaa erittäin tehokas ja hyödyllinen keino, jonka avulla voit pilkata ja tynkä pois nämä ei-toivottuja sivuvaikutuksia.,
Huomautus: mock
on hiljattain sisällytetty standardin kirjaston Python 3.3; ennen jakaumat täytyy käyttää Mock kirjasto ladattavissa kautta PyPI.
Järjestelmä Vaatii vs. Python Pilkaten
antaa sinulle toinen esimerkki, ja yksi että me ajaa koko artikkelin, harkitse järjestelmä puhelut., Se ei ole vaikea nähdä, että nämä ovat prime ehdokkaita pilkaten: olitpa kirjallisesti käsikirjoituksen eject CD-asema, web-palvelin, joka poistaa vanhentuneita välimuistin tiedostoja /tmp
, tai socket-palvelin, joka sitoutuu TCP-portti, nämä puhelut kaikki ominaisuus-toivottuja sivuvaikutuksia yhteydessä laite-testejä.
kehittäjänä välität enemmän siitä, että kirjastosi kutsui järjestelmäfunktiota onnistuneesti CD-levyn poistoon (oikeilla argumenteilla jne.) toisin kuin itse kokea CD tarjotin auki joka kerta, kun testi suoritetaan. (Tai pahempaa, useita kertoja, kuten useita testejä viittaus poistokoodi aikana yhden yksikön testi ajaa!)
Samoin, pitää laite-testejä tehokas ja suorituskykyinen tarkoittaa pitäminen mahdollisimman paljon ”hidasta koodi” ulos automatisoitu testi toimii, eli tiedostojärjestelmä-ja verkko-yhteys.,
ensimmäinen esimerkki, me refactor standardin Python koetinkivi alkaen alkuperäisessä muodossa käyttäen mock
. Näytämme, kuinka kirjoittaminen testi tapauksessa, jossa pilkkaa tekee meidän testit, älykkäämpi, nopeampi, ja voi paljastaa enemmän siitä, miten ohjelmisto toimii.
Yksinkertainen Poista Toiminto
Meidän täytyy poistaa tiedostoja meidän tiedostojärjestelmä ajoittain, joten on kirjoittaa funktio, Python, joka tekee siitä hieman helpompaa meidän skriptejä tehdä niin.,
#!/usr/bin/env python# -*- coding: utf-8 -*-import osdef rm(filename): os.remove(filename)
Tietenkin, meidän rm
menetelmä tällä hetkellä ei tarjoa paljon enemmän kuin taustalla os.remove
menetelmä, mutta meidän codebase parantaa, jotta voimme lisätä enemmän toimintoja täällä.
katsotaanpa kirjoittaa perinteinen testi tapauksessa, eli, ilman pilkkaa:
Meidän testi tapauksessa on melko yksinkertainen, mutta joka kerta se on ajaa, väliaikainen tiedosto on luotu ja sitten poistetaan., Lisäksi, meillä ei ole tapa testata, onko meidän rm
menetelmä oikein kulkee argumentti alas os.remove
puhelu. Voimme olettaa, että se perustuu edellä olevaan testiin, mutta paljon on vielä toivomisen varaa.
Refaktorointi Python Pilkkaa
oletetaan, refactor meidän testi tapauksessa käyttäen mock
:
näiden refactors, meillä on oleellisesti muuttunut siten, että testi toimii. Meillä on sisäpiiriläinen, esine, jolla voimme varmistaa toisen toimivuuden.,
Mahdolliset Python Pilkaten Sudenkuopat
Yksi ensimmäisiä asioita, joita pitäisi pysyä pois on, että käytämme mock.patch
menetelmä sisustusarkkitehti pilkata objekti sijaitsee osoitteessa mymodule.os
, ja suonensisäinen että pilkata meidän testi menetelmä. Eikö olisi järkevämpää vain pilkata os
itse, eikä viittaus siihen osoitteessa mymodule.os
?
no, Python on jonkin verran salakavala käärme mitä tulee moduulien tuontiin ja hallintaan., Runtime, mymodule
moduuli on oma os
joka on tuotu oma paikallinen ulottuvuus moduuli. Niinpä, jos me pilkata os
me ei nähdä vaikutuksia pilkata mymodule
moduuli.
mantraa pitää toistaa, on tämä:
Mock kohde, jossa sitä on käytetty, ei sitä, mistä se tuli.,
Jos sinun täytyy pilkata tempfile
moduuli myproject.app.MyElaborateClass
, olet todennäköisesti tarvitse hakea pilkata, jotta myproject.app.tempfile
, niin jokainen moduuli pitää omaa tuontia.
tuon kuopan kanssa pois tieltä, jatketaan pilkantekoa.
Lisäämällä Validointi ’rm’
rm
– menetelmällä määritetty aiemmin on varsin yksinkertaistettu. Haluaisimme, että se vahvistaa, että polku on olemassa, ja on tiedosto, ennen vain sokeasti yrittää poistaa sitä., Katsotaanpa refactor rm
olla hieman älykkäämpiä:
#!/usr/bin/env python# -*- coding: utf-8 -*-import osimport os.pathdef rm(filename): if os.path.isfile(filename): os.remove(filename)
Suuri. Tarkistetaan testitapauksemme, jotta se pysyy ajan tasalla.
testiparadigmamme on muuttunut täysin. Voimme nyt tarkistaa ja validoida menetelmien sisäistä toimivuutta ilman sivuvaikutuksia.
Tiedoston-Poisto palveluna kanssa Pilkata Patch
tähän mennessä olemme käyttäneet vain toimittaa pilkkaa toiminnot, mutta ei menetelmiä esineitä tai tapauksissa, joissa pilkka on tarpeen lähettää parametrit. Käydään ensin läpi objektimenetelmät.,
aloitamme rm
– menetelmän refaktorilla palveluluokkaan. Ei todellakaan ole perusteltua tarvetta, sinänsä, kiteyttää tällainen yksinkertainen funktio esine, mutta se tulee ainakin auttaa osoittamaan keskeiset käsitteet mock
. Katsotaanpa refactor:
huomaat, että paljon ei ole muuttunut meidän testata, jos:
Suuri, joten nyt tiedämme, että RemovalService
toimii, kuten on suunniteltu., Katsotaanpa luoda toinen palvelu, joka ilmoittaa sen riippuvuus:
Koska meillä on jo testi kattavuus RemovalService
, emme aio vahvistaa sisäistä toimivuutta rm
menetelmä meidän testit UploadService
. Pikemminkin, me yksinkertaisesti testi (ilman sivuvaikutuksia, tietenkin), että UploadService
puhelut RemovalService.rm
menetelmä, jonka tiedämme ”vain toimii™” meidän edellisen testin tapauksessa.
On olemassa kaksi tapaa edetä tästä:
- Pilkata ulos
RemovalService.rm
menetelmä itse., - toimittaa pilkatun instanssin
UploadService
konstruktorissa.
koska molemmat menetelmät ovat usein tärkeitä yksikkötestauksessa, käymme molemmat läpi.
Vaihtoehto 1: Pilkaten Esimerkiksi Menetelmiä
mock
kirjasto on erityinen menetelmä, sisustusarkkitehti pilkka esine esimerkiksi menetelmiä ja ominaisuuksia, @mock.patch.object
sisustaja:
– Hienoa! Olemme validoitu, että UploadService
onnistuneesti kutsuu meidän on esimerkiksi rm
menetelmä. Huomaatko mitään kiinnostavaa?, Kauneuspilkku mekanismi todella korvata rm
tapa kaikki RemovalService
tapauksissa meidän testi menetelmä. Se tarkoittaa, että voimme itse tutkia tapaukset. Jos haluat nähdä enemmän, kokeile pudottamalla keskeytyspisteen pilkkakoodiisi, jotta saat hyvän tuntuman siihen, miten paikkausmekanismi toimii.
Mock Patch Sudenkuoppa: Sisustusarkkitehti, Jotta
Kun käytät useita sisustussuunnittelijan teidän testi menetelmät, järjestys on tärkeä, ja se on aika hämmentävää. Periaatteessa, kun kartoitus sisustajat menetelmä parametrit, työskennellä taaksepäin., Mieti tätä esimerkkiä:
Huomaa, miten meidän parametrit on sovitettu päinvastaisessa järjestyksessä koristus? Se johtuu osittain Pythonin toimintatavasta. Useita menetelmä koristus, tässä järjestyksessä toteuttamista pseudokoodilla:
patch_sys(patch_os(patch_os_path(test_something)))
Koska laastari sys
on syrjäisimpien laastari, se toteutetaan viimeisenä, jolloin se on viimeinen parametri todellinen testi menetelmä argumentteja. Huomioi tämä hyvin ja käytä debuggeria testeissä varmistaaksesi, että oikeat parametrit pistetään oikeassa järjestyksessä.,
Vaihtoehto 2: Luo Mock Tapauksissa
sen Sijaan, pilkaten tiettyjä esimerkiksi menetelmää, voimme sen sijaan vain toimittaa pilkkasivat esimerkiksi UploadService
sen rakentaja. Mieluummin vaihtoehto 1 edellä, koska se on paljon tarkempi, mutta on monia tapauksia, joissa vaihtoehto 2 saattaa olla tehokasta tai tarpeellista. Katsotaanpa refactor meidän testi uudestaan:
tässä esimerkiksi, meillä ei ole ollut edes paikata mitään toimintoja, me yksinkertaisesti luoda auto-spec RemovalService
luokka, ja sitten pistää tässä tapauksessa meidän UploadService
vahvistaa toiminnallisuuden.,
mock.create_autospec
menetelmä luo toiminnallisesti vastaa esimerkiksi jos luokassa. Mitä tämä tarkoittaa käytännössä, että kun palauttaa esimerkiksi on vuorovaikutuksessa, se nostaa poikkeuksia, jos käyttää laittomia keinoja. Tarkemmin sanottuna, jos menetelmää kutsutaan väärällä perustelumäärällä, nostetaan esiin poikkeus. Tämä on erittäin tärkeää, koska refactors tapahtuu. Kirjaston vaihtuessa testit katkeavat ja sitä odotetaan. Ilman auto-spec, meidän testit on silti antaa, vaikka taustalla täytäntöönpano on rikki.,
Sudenkuoppa: mock.Mock
ja mock.MagicMock
Luokat
mock
kirjasto sisältää myös kaksi tärkeää luokkaa, johon useimmat sisäiset toiminnot on rakennettu: mock.Mock
ja mock.MagicMock
. Kun annetaan mahdollisuus käyttää mock.Mock
esimerkiksi mock.MagicMock
esimerkiksi, tai auto-spec, aina hyväksi käyttäen auto-spec, koska se auttaa pitämään testit järkevä tulevia muutoksia., Tämä on koska mock.Mock
ja mock.MagicMock
hyväksy kaikki metodikutsuja ja omaisuuden tehtäviä riippumatta taustalla API. Harkitse seuraavia käytä asia:
class Target(object): def apply(value): return valuedef method(target, value): return target.apply(value)
Emme voi testata tätä mock.Mock
esimerkiksi, kuten tämä:
Tämä logiikka näyttää terve, mutta katsotaanpa muuttaa Target.apply
menetelmä ottaa enemmän parametreja:
class Target(object): def apply(value, are_you_sure): if are_you_sure: return value else: return None
Re-tee testi, ja huomaat, että se vielä kulkee. Koska sitä ei ole rakennettu OHJELMOINTIRAJAPINTAASI vastaan., Tämä on miksi sinun pitäisi aina käyttää create_autospec
menetelmä ja autospec
parametri @patch
ja @patch.object
sisustussuunnittelijan.
Python Pilkata Esimerkki: Pilkaten Facebook API-Kutsu
loppuun asti, katsotaanpa kirjoittaa sovellettavissa reaalimaailman python pilkata esimerkki, joka olemme johdannossa: lähettämistä viestin Facebook. Kirjoitamme hyvän käärinluokan ja vastaavan testitapauksen.,
Tässä on meidän koetinkivi, joka tarkistaa, että me lähettää viestiä ilman todella lähettämistä viesti:
Kuten olemme nähneet tähän mennessä, se on todella helppo aloittaa kirjoittaminen älykkäämpiä testit mock
Python.
Johtopäätös
Python mock
library, jos hieman hämmentävää työskennellä, on peli-vaihtaja yksikkö-testaus. Olemme osoittaneet, yhteinen käyttö-tapauksissa saada alkoi käyttää mock
yksikkö-testaus, ja toivottavasti tämä artikkeli auttaa Python kehittäjät voittaa alkuperäisen esteitä ja kirjoittaa loistava, testattu koodi.,