Se on vain tosiasia, kuten koodin kasvaa lopulta sinun täytyy aloittaa lisäämällä pilkkaa sinun test suite. Söpönä pikku kakkosluokan projektina aloittanut puhuu nyt ulkoisille palveluille, eikä sitä voi enää testata mukavasti.

siksi Python-alukset unittest.mock, voimakas osa standardin kirjasto stubbing riippuvuudet ja pilkaten sivuvaikutuksia.

unittest.mock ei kuitenkaan ole erityisen intuitiivinen.,

– olen löytänyt itseni monta kertaa mietin, miksi minun go-resepti ei toimi tietyssä tapauksessa, joten olen koonnut tämän cheatsheet auttaa itseäni ja muita pilkkaa toimi nopeasti.

koodiesimerkit löytyvät artikkelin GitHub-arkistosta. Käytän Python 3.6, jos käytät 3.2 tai alla sinun täytyy käyttää mock PyPI paketti.,

esimerkit on kirjoitettu käyttäen unittest.TestCase luokat yksinkertaisuus suorittamista niitä ilman riippuvuuksia, mutta voit kirjoittaa niitä toimintoja käyttämällä pytest lähes suoraan,unittest.mock toimii hienosti. Jos olet pytest käyttäjä vaikka en rohkaista voit vilkaista erinomainen pytest-mock kirjasto.

centerpoint, että unittest.mock module on, tietenkin, Mock luokka., Tärkein ominaisuus Mock esine on, että se palaa taas Mock esimerkiksi, kun:

  • pääsy yksi sen ominaisuuksia
  • soittamalla esine itse

Tämä on oletusarvo käyttäytymistä, mutta se voidaan ohittaa eri tavoin. Esimerkiksi voit määrittää arvon määrite Mock esittäjä:

  • Liitä se suoraan, aivan kuten tekisit minkä tahansa Python objektin.,
  • Käytä configure_mock menetelmällä, esimerkiksi.
  • Tai siirtää avainsanan argumentteja Mock luokan luomiseen.

ohittaa puhelut pilkata sinun täytyy määrittää sen return_value omaisuutta, saatavana myös avainsanan argumentti Mock alustajan., Mock palaa aina sama arvo kaikki puhelut, tämä, jälleen, voidaan määrittää myös käyttämällä side_effect ominaisuus:

  • jos haluat palauttaa eri arvoja, jokaisen puhelun, voit määrittää iterable että side_effect.
  • Jos haluat nostaa poikkeus, kun soittaa Mock voit yksinkertaisesti määrittää ottamatta objekti side_effect.,

kaikki nämä työkalut, voimme nyt luoda tyngät lähinnä tahansa Python objektin, joka toimii suuri tuotantopanosten meidän järjestelmä. Mutta entä tuotokset?

Jos teet CLI-ohjelma ladata koko Internet, et luultavasti halua ladata koko Internet-kunkin testin. Sen sijaan riittäisi väittämään, että requests.download_internet (ei todellinen menetelmä) kutsuttiin asianmukaisesti. Mock antaa siihen käteviä menetelmiä.,

Huomautus tässä esimerkissä assert_called_once ei, tämä esittelee toinen keskeinen näkökohta Mock esineitä, ne tallentaa kaikki interaktio heidän kanssaan ja voit sitten tarkastaa näiden vuorovaikutusta.

esimerkiksi et voi käyttää call_count hakea puheluiden Mock ja käyttää call_args tai call_args_list tarkastaa argumentteja viimeinen tai kaikki puhelut vastaavasti.,

Jos tämä on hankalaa, voit milloin tahansa käyttää reset_mock tapa tyhjentää tallennetut interaktio, huomaa kokoonpano ei nollata, vain vuorovaikutusta.

Lopuksi, sallikaa minun esitellä MagicMock, alaluokka Mock, joka toteuttaa default magic tai dunder menetelmiä. Tämä tekee MagicMock ihanteellinen mock-luokan käyttäytyminen, joka on, miksi se on oletuksena luokassa, kun kauneuspilkku.,

olemme nyt valmiita aloittamaan irvailun ja eristämään yksikön testeissä. Tässä muutamia reseptejä pitää mielessä:

Laastari tuonti

tärkein tapa käyttää unittest.mock on laastari tuonti moduuli testattavan käyttäen patch toiminto.

patch siepata import lausunnot tunnistaa merkkijono (siitä lisää myöhemmin), ja palauttaa Mock esimerkiksi voit määrittää valmiiksi käyttämällä tekniikoita olemme keskustelleet edellä.,

Kuvittele, että haluamme testata tämän hyvin yksinkertainen tehtävä:

Huomaa, että olemme tuominen os ja soittaa getcwd saada nykyisen työhakemiston. Emme halua kutsua sitä testeissämme, vaikka se ei ole tärkeää koodillemme ja palautusarvo voi vaihdella ympäristöjen välillä.

Kuten edellä mainittiin, meidän täytyy toimittaa patch merkkijono, joka edustaa meitä erityiset tuontia., Emme halua toimittaa vain os.getcwd sillä se ei yhdistä kaikki moduulit, sen sijaan haluamme toimittaa moduulin alla testi on import ja os eli work.os . Kun moduuli on tuotu patch toimii sen taika ja palauttaa Mock sijaan.,

Vaihtoehtoisesti, voimme käyttää sisustusarkkitehti versio patch , huomaa tämä, kun testi on ylimääräinen parametri: mocked_os jossa Mock ruiskutetaan testi.,

patch toimittaa avainsanan argumentteja Mock luokan, joten voit määrittää return_value emme yksinkertaisesti lisää se yksi:

Pilkaten luokat

– Se on melko yleinen patch luokat täysin tai osittain., Helper "db"

  • Worker palauttaa odotettavissa polku toimittamien Helper
  • jotta testi Worker täydellisessä eristyksessä meidän täytyy paikata koko Helper class:

    Huomautus double return_value esimerkissä, yksinkertaisesti käyttämällä MockHelper.get_path.return_value ei toimisi sillä koodi me kutsumme get_path esimerkiksi, ei luokan itse.,

    ketjutus syntaksi on hieman sekava, mutta muista MagicMock palaa taas MagicMock puhelut __init__. Täällä olemme konfigurointi mitään fake Helper tapauksissa luoma MockHelper palaa, mitä me odotamme puhelut get_path mikä on ainoa tapa, me välitämme meidän testi.,

    Luokan speccing

    seuraus joustavuus Mock on, että kun olemme pilkkasivat luokan Python ei nosta AttributeError koska se yksinkertaisesti palaa uusia esiintymiä MagicMock periaatteessa kaikki. Tämä on yleensä hyvä asia, mutta voi johtaa joidenkin sekava käytös ja mahdollisesti vikoja. Esimerkiksi kirjoittaa seuraavaa testiä,

    hiljaa kulkea ilman varoitusta puuttuu kokonaan typo assrt_called_once .,

    Lisäksi, jos olimme nimetä Helper.get_path ja Helper.get_folder, mutta unohda päivittää soittaa Worker meidän testit on vielä läpäistävä:

    Onneksi Mock mukana tulee työkalu estää näitä virheitä, speccing.

    Yksinkertaisesti sanottuna, se ennakkoasetukset pilkkaa vastata vain menetelmiin, jotka todella ovat olemassa spec-luokassa., On olemassa useita tapoja määrittää, silmälasit, mutta helpoin on yksinkertaisesti pass autospec=True ja patch puhelu, joka määrittää Mock käyttäytyä kuin esine on pilkattu, nostaa poikkeuksia varten puuttuu ominaisuuksia ja virheelliset allekirjoitukset tarvittaessa., Esimerkiksi:

    Osittainen luokan pilkkaa

    Jos olet vähemmän taipuvaisia testaus täydellinen eristäminen voit myös osittain paikata luokan käyttäen patch.object:

    Täältä patch.object on antaa meille mahdollisuuden määrittää pilkkasivat versio get_path vain, jättäen loput käyttäytyminen koskemattomana., Tietenkin tämä tarkoittaa, että testi ei ole enää mitä ehdottomasti harkita yksikkötestin, mutta voit olla ok, että.

    Pilkaten rakennettu-in toimintoja, ja ympäristömuuttujat

    edellisissä esimerkeissä olemme laiminlyöty testata erityisesti yksi seikka, yksinkertainen luokka, print puhelu. Jos yhteydessä hakemuksesi tämä on tärkeää, kuten CLI-komento, esimerkiksi, meidän täytyy tehdä väitteitä vastaan tätä kutsua.,

    print – on, tietenkin sisäänrakennettu toiminto Python, mikä tarkoittaa, että meidän ei tarvitse tuoda se meidän moduuli, joka on vastoin sitä, mitä olemme edellä paikkauksesta tuonti., Silti kuvitella, että meillä oli tämä hieman monimutkaisempi versio meidän tehtävä:

    voidaan kirjoittaa testi, kuten seuraavat:

    Huom muutamia asioita:

    1. emme voi pilkata print kanssa mitään ongelmaa ja väittää, että siellä oli puhelun jälkeen ”laastari tuo” sääntö. Tämä oli kuitenkin muutos, joka otettiin käyttöön 3.,5, aiemmin sinun piti lisätä create=True ja patch puhelu signaali unittest.mockluoda Mock vaikka ei tuo vastaa tunniste.
    2. käytämme patch.dict pistää väliaikainen ympäristö muuttuja os.environ tämä on laajennettavissa muihin sanakirja haluamme pilkata.,
    3. olemme pesii useita patch context manager puhelut, mutta vain käyttämällä as ensimmäinen, koska se on yksi meidän täytyy soittaa assert_called_once_with .,

    Jos et ole ihastunut pesintä yhteydessä johtajien voit myös kirjoittaa patch puhelut sisustusarkkitehti muodossa:

    Huomaa kuitenkin, jotta argumentit testi sopii pinoaminen järjestyksessä, sisustussuunnittelijan, ja myös, että patch.dict ei pistä argumentti.,tämä on hyvin yleinen skenaario:

    Voit, tietenkin, lisää todellinen valaisin-tiedoston, mutta todellisessa maailmassa tapauksissa se voisi olla vaihtoehto, sen sijaan voimme pilkata yhteydessä manager on lähtö olla StringIO kohde:

    Ei ole mitään erityistä täällä paitsi maaginen __enter__ menetelmä, meidän täytyy vain muistaa taustalla oleva mekaniikka yhteydessä johtajat ja jotkut näppärä käyttää meidän luotettava MagicMock .,

    Pilkkaluokan attribuutit

    on monia tapoja saavuttaa tämä, mutta jotkut ovat typerämpiä todisteita siitä, että toiset. Oletetaan, että olet kirjoittanut seuraavan koodin:

    Voit testata koodia ilman mitään pilkkaa kahdella tavalla:

    1. Jos koodi testattavan käyttää määritteen kautta self.ATTRIBUTE, joka tapauksessa tässä esimerkissä, voit yksinkertaisesti aseta attribuutin suoraan esimerkiksi. Tämä on melko turvallista, koska muutos rajoittuu tähän yksittäiseen tapaukseen.,
    2. Vaihtoehtoisesti voit myös asettaa ominaisuuden tuontiluokassa testissä ennen instanssin luomista. Tämä kuitenkin muuttaa luokan ominaisuus olet tuonut testiin, joka voi vaikuttaa seuraaviin testeihin, joten sinun täytyy muistaa nollata se.

    suurin haittapuoli tämän non-Mock lähestymistapoja on, että jos et missään vaiheessa nimetä ominaisuus testeistä epäonnistuu, ja virhe ei suoraan mainita, että tämä nimeäminen epäsuhta.,

    ratkaista, että voimme käyttää patch.object tuodut luokan, joka valittaa, jos luokassa ei ole määritelty ominaisuus.

    Tässä ovat jotkut testit käyttäen kunkin tekniikka:

    Pilkaten luokan auttajia

    seuraava esimerkki on juuri monia ongelmia monkeypatching käyttää Pilkata. Se näkyy yleensä kypsemmillä koodebaaseilla, jotka alkavat hyödyntää kehyksiä ja auttajia luokkamäärittelyssä., Esimerkiksi, kuvitella, että tämä hypoteettinen Field helper class:

    Sen tarkoitus on paketoida ja parantaa määrite toiseen luokkaan, melko kuvio yleisesti voi nähdä ORMs tai muodossa kirjastot. Älä huoli itseäsi liian paljon yksityiskohtia se vain huomaa, että on olemassa type ja default arvo läpäissyt.,

    Nyt ottaa toinen näyte tuotanto koodi:

    Tämä luokka käyttää Field luokan määrittelemällä sen country ominaisuus kuin yksi, jonka tyyppi on str ja default ensimmäinen elementti COUNTRIES vakio. Testin logiikkana on, että maasta riippuen alennusta sovelletaan.,

    joista voimme kirjoittaa seuraava testi:

    Mutta se EI kulje.,

    käydään läpi testi:

    1. Ensin se laastaria oletuksena maiden pricer lista yhden merkinnän GB ,
    2. Tämä pitäisi tehdä CountryPricer.country attribuutti, default, että merkintä koska se määritelmä sisältää default=COUNTRIES ,
    3. Se sitten instanciates CountryPricer ja pyytää alennettuun hintaan GB !

    So what ’ s going on?,

    perussyy tähän on Python käyttäytymistä tuonnin aikana, parhaiten kuvata Luciano Ramalho on erinomainen Sujuva Python 21 luku:

    luokat, tarina on erilainen: milloin tuo aika, tulkki suorittaa kehon jokaisen luokan, jopa kehon luokat, sisäkkäisiä muissa luokissa. Luokkarungon toteutus tarkoittaa sitä, että luokan attribuutit ja menetelmät määritellään, ja sitten itse luokkaobjekti rakennetaan.,

    Soveltamalla tätä meidän esimerkki:

    1. country attribuutin Field oikeusasteen tuomioistuin on rakennettu ennen testiä on juoksi tuo aika,
    2. Python lukee kehon luokan kulkee COUNTRIES, joka on määritelty tässä vaiheessa Field esimerkiksi
    3. Meidän testi koodi toimii, mutta se on liian myöhäistä paikata COUNTRIES ja saada oikea väite.,

    edellä kuvaus voit kokeilla viivästyttää tuonti moduuli, kunnes sisällä testejä, jotain:

    Tämä, kuitenkin, ei ole vielä ohi kuten mock.patch tuo moduuli ja sitten monkeypatch se, mikä samassa tilanteessa kuin ennen.,

    Voit kiertää tämän, meidän täytyy omaksua valtion CountryPricer luokka aikaan testin ja patch default jo alustettu Field esimerkiksi:

    Tämä ratkaisu ei ole ihanteellinen, koska se vaatii tietoa sisäosat Field joka ei välttämättä ole tai halua käyttää, jos käytät ulkoista kirjastosta, mutta se toimii tässä tosin yksinkertaistettu tapaus.,

    tämä maahantuonnin aikanumero on yksi suurimmista ongelmista, joita olen kohdannut unittest.mock. Sinun täytyy muistaa, kun käytät sitä, että tuonnin aikakoodi huipputasolla moduulit suoritetaan, mukaan lukien luokan elimet.

    Jos logiikka olet testaus on riippuvainen tästä mitään logiikkaa, voit joutua uudelleen, miten käytät patch vastaavasti.,

    niputtamiseen

    Tämä käyttöönotto ja cheatsheet pitäisi saada sinut pilkaten unittest.mock, mutta kehotan teitä lue ohjeet huolellisesti, siellä on paljon enemmän mielenkiintoisia temppuja oppia.

    Se on syytä mainita, että on olemassa vaihtoehtoja unittest.mock erityisesti Alex Gaynor on pretend kirjasto yhdessä pytest’s monkeypatch ottelua. Kuten Alex huomauttaa, käyttämällä näitä kahta kirjastoa voit tehdä pilkkaamisesta tiukempaa ja ennustettavampaa., Ehdottomasti lähestymistapa kannattaa tutkia, mutta ulkopuolella tämän artikkelin.

    unittest.mock on tällä hetkellä standardi pilkaten Python ja löydät sen lähes joka codebase. Ottaa vankka ymmärrys siitä auttaa sinua kirjoittamaan parempia testejä nopeammin.

    Articles

    Vastaa

    Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *