Omandage pytest'i tööriistad tõhusaks ja hooldatavaks testimiseks. Õppige sõltuvuste sissepritse põhimõtteid ja praktilisi näiteid vastupidavate testide kirjutamiseks.
Pytest Fixture'id: Sõltuvuste Sissepritse Vastupidavaks Testimiseks
Tarkvaraarenduse valdkonnas on vastupidav ja usaldusväärne testimine ülimalt tähtis. Pytest, populaarne Pythoni testimisraamistik, pakub võimsat funktsiooni nimega tööriistad (fixtures), mis lihtsustab testide ettevalmistamist ja koristamist, soodustab koodi taaskasutatavust ja parandab testide hooldatavust. Käesolev artikkel käsitleb pytest'i tööriistade kontseptsiooni, uurides nende rolli sõltuvuste sissepritstes ja esitades praktilisi näiteid nende tõhususe illustreerimiseks.
Mis on Pytest Fixture'id?
Põhimõtteliselt on pytest'i tööriistad funktsioonid, mis pakuvad testide usaldusväärseks ja korduval täitmiseks fikseeritud alusbaasi. Need toimivad sõltuvuste sissepritse mehhanismina, võimaldades teil määratleda korduvkasutatavaid ressursse või konfiguratsioone, millele saab mitu testfunktsiooni hõlpsasti juurde pääseda. Mõelge neile kui tehasele, mis valmistab ette keskkonna, mida teie testid vajavad õigeks käivitamiseks.
Erinevalt traditsioonilistest ettevalmistus- ja koristamismeetoditest (nagu setUp
ja tearDown
unittest
-is) pakuvad pytest'i tööriistad suuremat paindlikkust, modulaarsust ja koodikorraldust. Need võimaldavad teil sõltuvusi selgesõnaliselt määratleda ja nende elutsüklit puhtal ja kokkusobival viisil hallata.
Sõltuvuste Sissepritse Selgitus
Sõltuvuste sissepritse on disainimuster, mille puhul komponendid saavad oma sõltuvused välistest allikatest, mitte ei loo neid ise. See soodustab nõrka sidumist, muutes koodi modulaarsemaks, testitavamaks ja hooldatavamaks. Testimise kontekstis võimaldab sõltuvuste sissepritse teil hõlpsasti asendada tegelikud sõltuvused jäljendobjektide või testdoblitega, mis võimaldab teil isoleerida ja testida üksikuid koodiüksusi.
Pytest'i tööriistad hõlbustavad sõltuvuste sissepritset sujuvalt, pakkudes mehhanismi testfunktsioonidele nende sõltuvuste deklareerimiseks. Kui testfunktsioon taotleb tööriista, täidab pytest automaatselt tööriista funktsiooni ja süstib selle tagastatud väärtuse argumendina testfunktsiooni.
Pytest'i Tööriistade Kasutamise Eelised
Pytest'i tööriistade kasutamine teie testimisprotsessis pakub mitmeid eeliseid:
- Koodi Taaskasutatavus: Tööriistu saab kasutada mitmes testfunktsioonis, välistades koodi dubleerimise ja soodustades järjepidevust.
- Testide Hooldatavus: Sõltuvuste muudatusi saab teha ühes kohas (tööriista definitsioonis), vähendades vigade riski ja lihtsustades hooldust.
- Parem Loetavus: Tööriistad muudavad testfunktsioonid loetavamaks ja keskendunumaks, kuna need deklareerivad selgesõnaliselt oma sõltuvused.
- Lihtsustatud Ettevalmistus ja Koristamine: Tööriistad haldavad ettevalmistus- ja koristamiskoodi automaatselt, vähendades testfunktsioonides korduvat koodi.
- Parameetrite Seadmine: Tööriistu saab parameetriseerida, võimaldades teil käivitada teste erinevate sisendandmete komplektidega.
- Sõltuvuste Haldus: Tööriistad pakuvad selget ja otsest viisi sõltuvuste haldamiseks, muutes testkeskkonna mõistmise ja kontrollimise lihtsamaks.
Lihtne Tööriista Näide
Alustame lihtsa näitega. Oletagem, et peate testima funktsiooni, mis suhtleb andmebaasiga. Andmebaasiühenduse loomiseks ja konfigureerimiseks võite defineerida tööriista:
import pytest
import sqlite3
@pytest.fixture
def db_connection():
# Ettevalmistus: looge andmebaasiĂĽhendus
conn = sqlite3.connect(':memory:') # Kasutage testimiseks mälus olevat andmebaasi
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT
)
""")
conn.commit()
# Pakkuge ĂĽhenduse objekt testidele
yield conn
# Koristamine: sulgege ĂĽhendus
conn.close()
def test_add_user(db_connection):
cursor = db_connection.cursor()
cursor.execute("INSERT INTO users (name, email) VALUES (?, ?)", ('John Doe', 'john.doe@example.com'))
db_connection.commit()
cursor.execute("SELECT * FROM users WHERE name = ?", ('John Doe',))
result = cursor.fetchone()
assert result is not None
assert result[1] == 'John Doe'
assert result[2] == 'john.doe@example.com'
Selles näites:
@pytest.fixture
dekoraator märgibdb_connection
funktsiooni tööriistana.- Tööriist loob mälus SQLite'i andmebaasiühenduse, loob
users
tabeli ja annab ĂĽhenduse objekti. yield
lause eraldab ettevalmistus- ja koristamisfaasid. Kood enneyield
täidetakse enne testi ja kood pärastyield
täidetakse pärast testi.test_add_user
funktsioon taotlebdb_connection
tööriista argumendina.- Pytest täidab automaatselt
db_connection
tööriista enne testi käivitamist, pakkudes andmebaasiühenduse objekti testfunktsioonile. - Pärast testi lõppu täidab pytest tööriistas koristamiskoodi, sulgedes andmebaasiühenduse.
Tööriista Ulatus (Scope)
Tööriistadel võib olla erinev ulatus, mis määrab, kui sageli neid täidetakse:
- function (vaikimisi): Tööriista täidetakse üks kord iga testfunktsiooni kohta.
- class: Tööriista täidetakse üks kord iga testklassi kohta.
- module: Tööriista täidetakse üks kord iga mooduli kohta.
- session: Tööriista täidetakse üks kord iga testistungi kohta.
Tööriista ulatuse saate määrata, kasutades parameetrit scope
:
import pytest
@pytest.fixture(scope="module")
def module_fixture():
# Ettevalmistuskood (täidetakse üks kord mooduli kohta)
print("Mooduli ettevalmistus")
yield
# Koristuskood (täidetakse üks kord mooduli kohta)
print("Mooduli koristus")
def test_one(module_fixture):
print("Test ĂĽks")
def test_two(module_fixture):
print("Test kaks")
Selles näites täidetakse module_fixture
ainult ĂĽks kord mooduli kohta, olenemata sellest, kui palju testfunktsioone seda taotleb.
Tööriista Parameetriseerimine
Tööriistu saab parameetriseerida, et käivitada teste erinevate sisendandmete komplektidega. See on kasulik sama koodi testimiseks erinevate konfiguratsioonide või stsenaariumitega.
import pytest
@pytest.fixture(params=[1, 2, 3])
def number(request):
return request.param
def test_number(number):
assert number > 0
Selles näites on number
tööriist parameetriseeritud väärtustega 1, 2 ja 3. test_number
funktsiooni käivitatakse kolm korda, üks kord iga number
tööriista väärtuse kohta.
Saate kasutada ka pytest.mark.parametrize
, et parameetriseerida testfunktsioone otse:
import pytest
@pytest.mark.parametrize("number", [1, 2, 3])
def test_number(number):
assert number > 0
See saavutab sama tulemuse kui parameetriseeritud tööriista kasutamine, kuid see on lihtsamate juhtumite korral sageli mugavam.
`request` Objekti Kasutamine
request
objekt, mis on tööriistafunktsioonides argumendina saadaval, pakub juurdepääsu erinevale kontekstuaalsele teabele tööriista taotleva testfunktsiooni kohta. See on FixtureRequest
klassi eksemplar ja võimaldab tööriistadel olla dünaamilisemad ja kohaneda erinevate testimisstseenidega.
request
objekti levinumad kasutusjuhtumid on:
- Testfunktsiooni Nime Juurdepääs:
request.function.__name__
annab tööriista kasutava testfunktsiooni nime. - Mooduli ja Klassi Teabe Juurdepääs: Testfunktsiooni sisaldavale moodulile ja klassile pääsete juurde vastavalt
request.module
jarequest.cls
kaudu. - Tööriistaparameetrite Juurdepääs: Parameetriseeritud tööriistu kasutades annab
request.param
teile juurdepääsu praegusele parameetri väärtusele. - Käsurea Valikute Juurdepääs: Pytest'ile edastatud käsurea valikutele pääsete juurde
request.config.getoption()
kaudu. See on kasulik tööriistade konfigureerimiseks kasutaja määratud seadete põhjal. - Lõpetajate Lisamine:
request.addfinalizer(finalizer_function)
võimaldab teil registreerida funktsiooni, mida täidetakse pärast testfunktsiooni lõpetamist, olenemata sellest, kas test läbis või ebaõnnestus. See on kasulik koristustoimingute jaoks, mida tuleb alati teha.
Näide:
import pytest
@pytest.fixture(scope="function")
def log_file(request):
test_name = request.function.__name__
filename = f"log_{test_name}.txt"
file = open(filename, "w")
def finalizer():
file.close()
print(f"\nSuletud logifail: {filename}")
request.addfinalizer(finalizer)
return file
def test_with_logging(log_file):
log_file.write("See on test logisõnum\n")
assert True
Selles näites loob log_file
tööriist logifaili, mis on spetsiifiline testfunktsiooni nimele. finalizer
funktsioon tagab logifaili sulgemise pärast testi lõppu, kasutades puhastusfunktsiooni registreerimiseks request.addfinalizer
.
Tavalised Tööriista Kasutusjuhtumid
Tööriistad on mitmekülgsed ja neid saab kasutada erinevates testimisstseenides. Siin on mõned tavalised kasutusjuhtumid:
- Andmebaasiühendused: Nagu eelmises näites näidati, saab tööriistu kasutada andmebaasiühenduste loomiseks ja haldamiseks.
- API Kliendid: Tööriistad saavad luua ja konfigureerida API kliente, pakkudes ühtset liidest väliskeskkondadega suhtlemiseks. Näiteks, kui testitakse ülemaailmset e-kaubanduse platvormi, võite omada tööriistu erinevate piirkondlike API lõpp-punktide jaoks (nt
api_client_us()
,api_client_eu()
,api_client_asia()
). - Konfiguratsiooniseaded: Tööriistad saavad laadida ja pakkuda konfiguratsiooniseadeid, võimaldades testidel erinevate konfiguratsioonidega käivituda. Näiteks, tööriist võiks laadida konfiguratsiooniseadeid keskkonna (arendus, testimine, tootmine) põhjal.
- Jäljendobjektid: Tööriistad saavad luua jäljendobjekte või testdoblesid, võimaldades teil isoleerida ja testida üksikuid koodiüksusi.
- Ajutised Failid: Tööriistad saavad luua ajutisi faile ja katalooge, pakkudes puhast ja isoleeritud keskkonda failipõhisteks testideks. Kaaluge funktsiooni testimist, mis töötleb pildifaile. Tööriist võiks luua testide jaoks kasutamiseks erinevate omadustega näidisepildifailide komplekti (nt JPEG, PNG, GIF).
- Kasutaja Autentimine: Tööriistad saavad hallata kasutaja autentimist veebirakenduste või API-de testimiseks. Tööriist võiks luua kasutajakonto ja saada autentimistunnuse, mida kasutada järgnevates testides. Mitmekeelsete rakenduste testimisel võiks tööriist luua erinevate keele-eelistustega autentitud kasutajaid, et tagada õige lokaliseerimine.
Täiustatud Tööriista Tehnikad
Pytest pakub mitmeid täiustatud tööriista tehnikaid teie testimisvõimaluste parandamiseks:
- Automaatne Tööriistade Kasutamine: Parameetrit
autouse=True
saate kasutada tööriista automaatseks rakendamiseks kõigile testfunktsioonidele moodulis või seansis. Kasutage seda ettevaatlikult, kuna kaudsed sõltuvused võivad testide mõistmist raskendada. - Tööriista Nimemisruumid: Tööriistad on defineeritud nimemisruumis, mida saab kasutada nimekollisioonide vältimiseks ja tööriistade loogilistesse gruppidesse korraldamiseks.
- Tööriistade Kasutamine Failis conftest.py: Failis
conftest.py
defineeritud tööriistad on automaatselt saadaval kõigile samas kataloogis ja selle alamkataloogides asuvatele testfunktsioonidele. See on hea koht tavaliselt kasutatavate tööriistade defineerimiseks. - Tööriistade Jagamine Projektide Vahel: Saate luua korduvkasutatavaid tööriistade raamatukogusid, mida saab jagada mitme projekti vahel. See soodustab koodi taaskasutamist ja järjepidevust. Kaaluge tavaliste andmebaasitööriistade raamatukogu loomist, mida saab kasutada mitmes rakenduses, mis suhtlevad sama andmebaasiga.
Näide: API Testimine Tööriistadega
Illustreerime API testimist tööriistadega hüpoteetilise näite abil. Oletagem, et testite globaalse e-kaubanduse platvormi API-d:
import pytest
import requests
BASE_URL = "https://api.example.com"
@pytest.fixture
def api_client():
session = requests.Session()
session.headers.update({"Content-Type": "application/json"})
return session
@pytest.fixture
def product_data():
return {
"name": "Globaalne Toode",
"description": "Ăślemaailmselt saadaval olev toode",
"price": 99.99,
"currency": "USD",
"available_countries": ["US", "EU", "Asia"]
}
def test_create_product(api_client, product_data):
response = api_client.post(f"{BASE_URL}/products", json=product_data)
assert response.status_code == 201
data = response.json()
assert data["name"] == "Globaalne Toode"
def test_get_product(api_client, product_data):
# Esiteks looge toode (oletades, et test_create_product töötab)
response = api_client.post(f"{BASE_URL}/products", json=product_data)
product_id = response.json()["id"]
# NĂĽĂĽd hankige toode
response = api_client.get(f"{BASE_URL}/products/{product_id}")
assert response.status_code == 200
data = response.json()
assert data["name"] == "Globaalne Toode"
Selles näites:
api_client
tööriist loob korduvkasutatava päringute seansi vaikimisi sisutüübiga.product_data
tööriist pakub näidis toote koormatoodet toodete loomiseks.- Testid kasutavad neid tööriistu toodete loomiseks ja hankimiseks, tagades puhtad ja järjepidevad API interaktsioonid.
Parimad Praktikad Tööriistade Kasutamiseks
Pytest'i tööriistade eeliste maksimeerimiseks järgige neid parimaid praktikaid:
- Hoidke Tööriistad Väikeste ja Keskendunud: Igal tööriistal peaks olema selge ja spetsiifiline eesmärk. Vältige liiga keerukate tööriistade loomist, mis teevad liiga palju.
- Kasutage Tähendusrikkaid Tööriista Nimesid: Valige oma tööriistadele kirjeldavad nimed, mis selgelt näitavad nende eesmärki.
- Vältige Kõrvalmõjusid: Tööriistad peaksid peamiselt keskenduma ressursside ettevalmistamisele ja pakkumisele. Vältige toimingute tegemist, mis võivad teistel testidel soovimatuid kõrvalmõjusid avaldada.
- Dokumenteerige Oma Tööriistad: Lisage oma tööriistadele dokumentatsioonid, et selgitada nende eesmärki ja kasutamist.
- Kasutage Tööriista Ulatusi Sobivalt: Valige sobiv tööriista ulatus sõltuvalt sellest, kui sageli tuleb tööriista täita. Ärge kasutage seansipõhist tööriista, kui funktsioonipõhisest tööriistast piisab.
- Kaaluge Testi Isolatsiooni: Veenduge, et teie tööriistad pakuvad testide vahel piisavat isolatsiooni, et vältida nende sekkumist. Näiteks kasutage iga testfunktsiooni või mooduli jaoks eraldi andmebaasi.
Kokkuvõte
Pytest'i tööriistad on võimas vahend vastupidavate, hooldatavate ja tõhusate testide kirjutamiseks. Sõltuvuste sissepritse põhimõtteid omaks võttes ja tööriistade paindlikkust ära kasutades saate oluliselt parandada oma tarkvara kvaliteeti ja usaldusväärsust. Alates andmebaasiühenduste haldamisest kuni jäljendobjektide loomiseni pakuvad tööriistad puhast ja organiseeritud viisi testide ettevalmistuse ja koristamise haldamiseks, mis viib loetavamate ja keskendunumate testfunktsioonideni.
Järgides käesolevas artiklis kirjeldatud parimaid praktikaid ja uurides saadaolevaid täiustatud tehnikaid, saate vabastada pytest'i tööriistade täieliku potentsiaali ja tõsta oma testimisvõimalusi. Pidage meeles, et prioriteediks peaks olema koodi taaskasutatavus, testi isolatsioon ja selge dokumentatsioon, et luua tõhus ja hõlpsalt hooldatav testimiskeskkond. Kui jätkate pytest'i tööriistade integreerimist oma testimisprotsessi, avastate, et need on kvaliteetse tarkvara loomisel hädavajalikud vahendid.
Lõppkokkuvõttes on pytest'i tööriistade omandamine investeering teie tarkvaraarenduse protsessi, mis suurendab teie koodibaasi usaldust ja sujuvamat teed usaldusväärsete ja vastupidavate rakenduste tarnimiseks kasutajatele kogu maailmas.