Bevezetés Gúnyos Python

, Hogyan kell Futtatni a Unit Tesztek Python Vizsgálat Nélkül A Türelem

Még gyakoribb, mint nem, a szoftver írunk közvetlenül kommunikál, mi a címke, mint a “piszkos” szolgáltatást. Laikus szempontból: olyan szolgáltatások, amelyek kulcsfontosságúak az alkalmazásunk számára, de amelyek kölcsönhatásai szándékoltak, de nem kívánt mellékhatások-azaz nem kívánatosak egy autonóm tesztfutás keretében.,a facebook facebook új funkciójának kipróbálására is készülünk, de nem szeretnénk, ha a tesztcsomagunk futtatásakor tényleg minden alkalommal posztolnánk a Facebookra.

a Pythonunittest könyvtár tartalmaz egy alcsomagot nevűunittest.mock—vagy ha nyilvánítja, hogy a függőség, egyszerűenmock—amely rendkívül erős és hasznos eszköz, amellyel kigúnyolják és csonk ki ezeket a nemkívánatos mellékhatásokat.,

Megjegyzés: mock újonnan szerepel a standard könyvtár, mint a Python 3.3; előzetes Mockutions kell használni a könyvtár letölthető PyPI.

System Calls vs. Python gúnyos

, hogy egy másik példa, és az egyik, hogy fogunk futni a többi cikk, fontolja meg a rendszer hívásokat., Nem nehéz belátni, hogy ezek a miniszterelnök-jelöltek gúnyolódik: e-forgatókönyvet írsz, hogy vegye ki a CD-meghajtó, egy web szerver, amely eltávolítja elavult cache fájlokat /tmp, vagy a socket szerver, amely kötődik egy TCP port, ezek a hívások az összes funkció nem kívánt mellékhatások összefüggésben a unit-tesztet.

fejlesztőként jobban érdekli, hogy a könyvtár sikeresen felhívta a CD kiadásának rendszerfunkcióját, szemben azzal, hogy a CD-tálcát minden teszt futtatásakor nyitva tartja.,

fejlesztőként jobban érdekli, hogy a könyvtár sikeresen felhívta a CD kiadására szolgáló rendszerfunkciót (a megfelelő argumentumokkal stb.) szemben a ténylegesen tapasztalható a CD-tálca nyitva minden alkalommal, amikor egy teszt fut. (Vagy ami még rosszabb, többször is, mivel több teszt hivatkozik a kiadás kódjára egyetlen egység-teszt futás közben!)

Hasonlóképpen, miközben a unit-teszteket hatékony, nagy teljesítményű azt jelenti, hogy annyi “lassú kód” az automatizált teszt fut, azaz fájlrendszer, illetve a hálózati hozzáférést.,

az első példánkhoz egy szabványos Python teszt esetet az eredeti űrlapról az egyikre refaktálunk a mockhasználatával. Bemutatjuk, hogy egy tesztesetünk hogyan teszi okosabbá, gyorsabbá a tesztjeinket, és hogyan tud többet megtudni a szoftver működéséről.

egy egyszerű törlési funkció

mindannyiunknak időről időre törölnie kell a fájlokat a fájlrendszerünkből, ezért írjunk egy funkciót Python-ban, amely kissé megkönnyíti a szkriptek számára.,

#!/usr/bin/env python# -*- coding: utf-8 -*-import osdef rm(filename): os.remove(filename)

nyilvánvaló, hogy a rm módszerünk ebben az időben nem nyújt sokkal többet, mint az alapul szolgáló os.remove módszer, de a codebase javulni fog, lehetővé téve számunkra, hogy itt több funkciót adjunk hozzá.

írjunk egy hagyományos tesztesetet, azaz gúnyolódás nélkül:

tesztesetünk nagyon egyszerű, de minden alkalommal, amikor fut, létrehoz egy ideiglenes fájlt, majd törli., Ezenkívül nincs módunk megvizsgálni, hogy a rmmódszerünk megfelelően átadja-e az argumentumot a os.remove hívásnak. Feltételezhetjük, hogy a fenti teszt alapján teszi, de sok kívánnivalót hagy maga után.

Refactoring with Python Mocks

nézzük refactoring our test case using mock:

ezekkel a refactorokkal alapvetően megváltoztattuk a teszt működésének módját. Most van egy bennfentes, egy objektum, amelyet felhasználhatunk egy másik funkciójának ellenőrzésére.,

Potenciális Piton Gúnyos Buktatókat

az Egyik első dolog, hogy tartsunk ki, hogy használjuk a mock.patch módszer, dekoratőr, hogy kigúnyolja az objektum található, mymodule.os lehetőséget, majd intravénás gúnyt űz a vizsgált esetben a módszer. Nem lenne több értelme, hogy csak gúnyolódni os maga, ahelyett, hogy a hivatkozás rá mymodule.os?

nos, Python kissé alattomos kígyó, amikor a behozatali és kezelési modulok., Futásidőben amymodule modulnak sajátos van, amelyet a modul saját helyi hatókörébe importálnak. Így ha a os nevet használjuk, akkor a mymodule modulban nem fogjuk látni a mock hatásait.

az ismétlődő mantra a következő:

Mock egy elemet, ahol használják, nem, ahol jött.,

Ha ki kell gúnyolni a tempfile modult myproject.app.MyElaborateClass, akkor valószínűleg alkalmazni kell a makett myproject.app.tempfile, mivel minden modul megtartja saját importját.

ezzel a bukással az útból, gúnyolódjunk tovább.

validáció hozzáadása az ” rm “

rm a korábban definiált módszer meglehetősen leegyszerűsítve. Szeretnénk, ha igazolná, hogy létezik egy elérési út, és egy fájl, mielőtt vakon megpróbálja eltávolítani., Nézzük refactor rm egy kicsit okosabb:

#!/usr/bin/env python# -*- coding: utf-8 -*-import osimport os.pathdef rm(filename): if os.path.isfile(filename): os.remove(filename)

nagyszerű. Most állítsuk be a teszt esetet, hogy a lefedettség fennmaradjon.

tesztelési paradigmánk teljesen megváltozott. Most már ellenőrizhetjük és érvényesíthetjük a módszerek belső funkcionalitását mellékhatások nélkül.

file-Removal as a Service with Mock Patch

eddig csak a funkciók gúnyolódásával dolgoztunk, de nem olyan objektumokra vagy esetekre vonatkozó módszerekre, ahol a paraméterek küldéséhez gúnyolódás szükséges. Először fedjük le az objektum módszereit.,

a rm módszer refaktorával kezdjük egy szolgáltatási osztályba. Valójában önmagában nincs szükség arra, hogy egy ilyen egyszerű függvényt egy objektumba ágyazzunk, de ez legalább segít nekünk a mockkulcsfogalmak bemutatásában. Nézzük refactor:

észre fogod venni, hogy a tesztesetben nem sokat változott:

nagyszerű, így most már tudjuk, hogy a RemovalService a tervek szerint működik., Hozzunk létre egy másik szolgáltatást, amely függőségnek nyilvánítja:

mivel már van teszt lefedettségünk a RemovalService, nem fogjuk érvényesíteni a rm módszer belső funkcionalitását a UploadServicetesztjeinkben. Inkább egyszerűen teszteljük (természetesen mellékhatások nélkül), hogy a UploadService felhívja a RemovalService.rm módszert, amelyről tudjuk, hogy “csak works™” a korábbi tesztesetünkből.

ennek két módja van:

  1. gúnyolja ki a RemovalService.rm módszert.,
  2. adjon meg egy gúnyos példányt a UploadServicekonstruktorában.

mivel mindkét módszer gyakran fontos az egységtesztelés során, mindkettőt áttekintjük.

1. Lehetőség: Mocking példány módszerek

a mock könyvtár egy speciális módszer dekoratőr gúnyos objektum példány módszerek és tulajdonságok, a @mock.patch.object dekoratőr:

nagy! Ellenőriztük, hogy aUploadService sikeresen hívja példányunkrm metódusát. Észrevettél valami érdekeset?, A patching mechanizmus valójában felváltotta arm módszer mindenRemovalService példányok a vizsgálati módszer. Ez azt jelenti, hogy valóban megvizsgálhatjuk az eseteket. Ha többet szeretne látni, próbáljon betörni egy töréspontot a gúnyos kódban, hogy jól érezze magát a javító mechanizmus működéséről.

Mock Patch Pitfall: Decorator Order

Ha több lakberendezőt használ a tesztelési módszereken, a sorrend fontos, és ez elég zavaró. Alapvetően, amikor a dekorátorokat a módszer paramétereihez térképezi, hátrafelé dolgozik., Tekintsük ezt a példát:

figyeljük meg, hogy paramétereink hogyan illeszkednek a dekorátorok fordított sorrendjéhez? Ez részben azért van, mert a Python működik. Több módszer lakberendezők, itt van az a kivégzés, a pszeudokód:

patch_sys(patch_os(patch_os_path(test_something)))

Mivel a patch sys a legkülső patch, akkor lehet végrehajtani, múlt, hogy az utolsó paraméter a tényleges vizsgálati módszer érvek. Vegye figyelembe ezt is, majd használja a hibakereső, amikor fut a tesztek, hogy megbizonyosodjon arról, hogy a megfelelő paramétereket fecskendeznek a megfelelő sorrendben.,

2. lehetőség: Mock példányok létrehozása

ahelyett, hogy gúnyolnánk az adott példány módszert, ehelyett csak egy gúnyolt példányt adhatunk meg a UploadService – nek a kivitelezőjével. Inkább a fenti 1. opciót részesítem előnyben, mivel ez sokkal pontosabb, de sok olyan eset van, amikor a 2.lehetőség hatékony vagy szükséges lehet. Nézzük refactor a tesztet újra:

ebben A példában, még nem is kellett javítás minden funkcionalitás, egyszerűen hozzon létre egy auto-spec a RemovalService osztály, majd be ebben az esetben a UploadService, hogy érvényesítse a funkciót.,

amock.create_autospec módszer funkcionálisan egyenértékű példányt hoz létre a megadott osztályhoz. Ez gyakorlatilag azt jelenti, hogy amikor a visszaküldött példány kapcsolatba kerül, kivételeket fog emelni, ha illegális módon használják. Pontosabban, ha egy módszert rossz számú érvvel hívnak, kivételt emelnek. Ez rendkívül fontos, mivel a refaktorok megtörténnek. Ahogy a könyvtár változik, a tesztek megszakadnak,és ez várható. Automatikus specifikáció használata nélkül a tesztek továbbra is elhaladnak, annak ellenére, hogy a mögöttes megvalósítás megtört.,

mock.Mock és mock.MagicMock osztályok

a mock A könyvtár két fontos osztályt is magában foglal, amelyekre a belső funkcionalitás nagy része épül: és mock.MagicMock. Ha a választás, hogy egy mock.Mock példány, a mock.MagicMock példány, vagy egy auto-spec, mindig előnyben egy auto-spec, mivel segít megőrizni a tesztek épelméjű jövőbeli változások., Ennek oka, hogy amock.Mock ésmock.MagicMock minden metódushívást és tulajdonság hozzárendelést Elfogad, függetlenül a mögöttes API-tól. Vegye figyelembe a következő használati esetet:

class Target(object): def apply(value): return valuedef method(target, value): return target.apply(value)

ezt egy mock.Mock példával tesztelhetjük:

Ez a logika normálisnak tűnik, de módosítsuk a módszer további paraméterek bevitelére:

class Target(object): def apply(value, are_you_sure): if are_you_sure: return value else: return None

futtassa újra a tesztet, majd kiderül, hogy még mindig elhalad. Ez azért van, mert nem a tényleges API-val szemben épül fel., Ezért kell mindig a create_autospec módszert és a autospec paramétert használni a @patch és @patch.object dekorátorokkal.a Facebook Facebook API-hívásának gúnyolódása

a befejezéshez írjunk egy alkalmazhatóbb valós Python mock példát, amelyet a bevezetőben említettünk: üzenet közzététele a Facebook-ra. Írunk egy szép csomagolóanyagot és egy megfelelő tesztesetet.,

itt van a tesztesetünk, amely ellenőrzi, hogy elküldjük-e az üzenetet anélkül, hogy ténylegesen közzétennénk az üzenetet:

ahogy eddig láttuk, nagyon egyszerű az okosabb tesztek írása a mock Python-ban.

következtetés

Python mock könyvtár, ha egy kicsit zavaró dolgozni, egy játék-váltó egység-tesztelés. Már bizonyított közös használata-esetekben a használatbavétel a mock az egység-vizsgálat, de remélhetőleg ez a cikk segít Python fejlesztők leküzdeni a kezdeti akadályokat, s ír kitűnő, kipróbált kódot.,

Share

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük