11.1 Miért írunk tesztet

← 11. TDD – Automatizált tesztek

11.1 Miért írunk teszteket? – A biztosítás metafora

Áttekintő

Ha valaha megváltoztattál egy kódrészletet, majd szorongva nézted, hogy vajon elromlott-e valami máshol – pontosan azt érzed, amit az automatizált tesztek kiváltanak. Ez az alfejezet nem arról szól, hogy megtanítson tesztelni – arról szól, hogy megértsd: miért érdemes egyáltalán teszteket írni, és mit vársz tőlük reálisan.

A teszt nem a fejlesztés ellenfele. Nem a bürokratikus overhead. Nem valami, amit a seniorok csak azért követelnek, mert „így szokás". A teszt a jövőbeli önmagad biztosítása – és ahogy egy lakásbiztosításra sem gondolsz minden nap, de hálás vagy, ha szükség van rá, ugyanúgy fog működni ez is.


Részletes leírás

A biztosítás metafora – miért pont ez?

Képzelj el két szituációt:

Szituáció A: Írsz egy funckiót, ami kiszámolja egy rendelés végösszegét. Majd 3 hónappal később kollégád hozzányúl, hogy kezelni tudja a kuponkódokat. Ő nem tudja, hogy te a végösszeg kiszámításában elrejtettél egy edge case-t: ha az ár nulla, ne kerüljön ki a számlából a kedvezmény. Nincs teszt. Ő nem is tud erről az esetről. Deploy. Production hiba. Dühös ügyfél.

Szituáció B: Ugyanaz a szituáció, de te írtál egy tesztet az edge case-re. Kolléga módosít. A teszt elbukik. Kolléga megkérdezi: „Mi ez a teszt?" Megnézi, megérti a logikát, javítja. Deploy. Nincs production hiba.

Ez a biztosítás. Nem boldogabbá teszi az életet – de megakadályozza a katasztrófát.


Mire jó valójában a teszt?

1. Regressziók felismerése

A „regresszió" szó azt jelenti: valami, ami korábban működött, elromlott. Ezek a legkellemetlenebb hibák, mert nem az új kódban keresed – hanem a régiben, amit véletlenül eltörtél.

Tesztek nélkül a regressziók vagy:

  • Ismeretlenek maradnak (és production-ban derül ki)
  • Manuálisan kell végigkattintani minden funkciót minden deploy előtt

Tesztekkel a CI pipeline automatikusan szól, ha valami eltört.

2. Refactoring félelem feloldása

Az egyik legnagyobb szimptóma, hogy egy codebase baj van: senki nem meri refaktorálni. Mindenki tudja, hogy a kód csúnya, de senki nem nyúl hozzá, mert „mi lesz, ha elromlik valami?"

Ez a refactoring paralízis. Ha van tesztlefedettség, bátran átírhatod a belsőt – amíg a tesztek zöldek, a viselkedés nem változott.

3. Dokumentáció mellékhatásként

Egy jól megírt teszt pontosan leírja, mire számítasz egy adott szituációban. Pl.:

def test_discount_not_applied_when_price_is_zero():
    order = Order(price=0)
    order.apply_coupon("SUMMER20")
    assert order.total == 0

Ez egy mondatnyi üzleti logika, amit bárki megért – kód olvasása nélkül. A teszt neve maga a dokumentáció.

4. Tervezés segítése

Ha a tesztet a kód előtt írják (erről szól majd a 11.3-as alfejezet), akkor a teszt a design eszköze is lesz. „Hogyan akarom ezt a funkciót meghívni?" – ez a kérdés kényszeríti ki a tiszta interfészeket.


Mikor NEM éri meg tesztet írni?

Ez az a pont, ahol a legtöbb anyag hazudik. Nem kell mindent tesztelni. Néhány eset, ahol a teszt értéke kérdéses:

Sokat változó, kísérletező kód
Ha egy feature prototípusát írod, és 80% eséllyel kukázod holnap, a teszt overhead. Tesztelj, ha a kód stabil és marad.

Triviális getter/setter

def get_name(self):
    return self.name

Ennek a tesztelése ceremony, nem értékteremtés. Ha a framework generálta, bízz benne.

UI layout részletek
Pixel-perfect tesztelés törékeny. Ha az elemek pozíciója változik, a teszt folyton elbukik okos ok nélkül. Inkább integrációs tesztek.

Egyszeri script
Ha valami egyszer fut le és eldobandó, tesztelés felesleges overhead.


Realista elvárások – mit NE várj a tesztektől

  • A teszt nem találja meg az összes bugot. Csak azokat, amikre írtál tesztet.
  • A teszt nem helyettesíti a code review-t. A logikailag rossz kód átmehet teszteken.
  • 100% coverage nem = hibamentes kód. Erről részletesen a 11.5-ös alfejezetben.
  • A tesztek is el tudnak romlani. Törékeny tesztek több bajt okoznak, mint hasznot (11.7).

Életszerű példák

Példa 1: Az éjféli deploy és a néma regresszió

Lili junior fejlesztő egy e-commerce projekten dolgozik. Kap egy ticketet: „Add hozzá az ingyenes szállítás logikáját 20.000 Ft felett." Megírja, kézzel leteszteli, működik. Deploy pénteken este.

Hétfőn reggel: az ügyfélszolgálat jelzi, hogy minden rendelésnél hibás az összeg. Kiderül: a szállítási költség számítása az order.total property-t hívja, amit Lili módosított a logikában. Nincs teszt, nincs visszajelzés. Hotfix-ek, stressz.

Ha lett volna egy teszt az order.total eredeti viselkedésére, a CI megállítja a deploy-t.


Példa 2: A félelmetes legacy modul

Péter csatlakozik egy 5 éves projekthez. Van egy pricing_engine.py nevű fájl, amit senki nem mer megnyitni. „Nem tudjuk, mit csinál pontosan, de működik" – mondják a kollégák.

Seniorja megkéri Pétert: írja le, amit megért belőle, tesztekbe. 2 nap alatt Péter teszteket ír, miközben megérti a logikát. Most:

  • Dokumentálva van, mit csinál
  • Bárki módosíthatja anélkül, hogy mindent félne
  • A refaktorálás megkezdődhet

Példa 3: Az interjú kérdés

Állásinterjún a senior megkérdezi: „Hogyan biztosítod, hogy a módosításod nem törte el az existing functionality-t?"

Teszt nélküli junior válasz: „Kézzel leteszteltem a főbb use case-eket."

Teszt-tudatos junior válasz: „Volt meglévő tesztsuite, ami lefutott. Ahol nem volt teszt, írtam egyet az érintett logikára, hogy a viselkedés dokumentált legyen."

A második válasz nem csak jobb technikai döntést mutat – azt jelzi, hogy a jelölt team-player, mert gondol a jövőbeli kollégákra is.


Tesztfeladatok

1. kérdés

Miért hívja ez az alfejezet a teszteket „biztosításnak"?

A) Mert drágák, mint a biztosítás
B) Mert nem boldogítanak naponta, de megakadályozzák a katasztrófát, amikor szükség van rájuk
C) Mert kötelező minden cégnél rendelkezni velük
D) Mert mindig 100%-ban megvédik a hibáktól

Helyes válasz: B


2. kérdés

Mi az a „regresszió" a szoftverfejlesztésben?

A) Régi kód újraírása modernebb technológiával
B) Olyan hiba, ami egy korábban működő funkciót elront
C) A kód visszafelé kompatibilitásának elvesztése
D) Teljesítményromlás az alkalmazásban

Helyes válasz: B


3. kérdés

Melyik állítás igaz a tesztek dokumentációs szerepéről?

A) A tesztek teljes mértékben helyettesítik a kóddokumentációt
B) Egy jól megnevezett teszt leírja, milyen viselkedést vár el egy adott szituációban
C) A tesztek csak a fejlesztőknek nyújtanak információt, nem az üzleti logikáról
D) Dokumentációs célra a kommentek hatékonyabbak, mint a tesztek

Helyes válasz: B


4. kérdés

Melyik esetben NEM éri meg általában tesztet írni?

A) Komplex üzleti logikánál
B) Régi kód refaktorálásánál
C) Prototípusnál, amit valószínűleg hamarosan eldobunk
D) Kritikus számítási funkciónál

Helyes válasz: C


5. kérdés

Mi a „refactoring paralízis"?

A) Amikor a fejlesztő nem tudja, hogyan kell refaktorálni
B) Amikor senki nem meri átírni a kódot, mert tartanak attól, hogy valamit elrontanak
C) Amikor a refaktorálás túl sokáig tart és blokkolja a feature fejlesztést
D) Amikor az IDE megakadályozza az automatikus refaktorálást

Helyes válasz: B


6. kérdés

Melyik állítás HAMIS a tesztekről?

A) A tesztek segítenek a regressziók felismerésében
B) 100%-os test coverage garantálja, hogy nincs bug a kódban
C) A tesztek dokumentációs mellékhatással is bírnak
D) A tesztek csökkentik a refaktorálástól való félelmet

Helyes válasz: B


7. kérdés

Az alábbi tesztnév közül melyik a leginkább dokumentáció-értékű?

A) test_1()
B) test_order()
C) test_discount_not_applied_when_price_is_zero()
D) test_apply_coupon_edge_case()

Helyes válasz: C
Magyarázat: A tesztnév pontosan leírja a szituációt és az elvárt viselkedést – ez a célja a teszt mint dokumentáció elvnek.


8. kérdés

Péter egy módosítást tesz az alkalmazásba, majd lefuttatja a meglévő teszteket. Minden teszt zöld. Melyik következtetés helyes?

A) A módosítás biztosan hibamentes
B) A módosítás nem rontott el semmit, amire volt teszt írva
C) A módosítás megfelel az összes üzleti követelménynek
D) A módosítás production-ready és deploy-olható

Helyes válasz: B
Magyarázat: A zöld tesztek csak azt garantálják, hogy a meglévő tesztek által lefedett esetek működnek. Ismeretlen hibák, lefedetlen esetek még benne lehetnek.


9. kérdés – Szituációs feladat

Anna egy számlázó rendszeren dolgozik. A calculate_vat() függvény kiszámolja az ÁFA összegét. Jelenleg ez a kód teszt nélkül van. Jövő héten fizetési módokat fog hozzáadni a rendszerhez.

Miért lenne hasznos, ha Anna most tesztet írna a calculate_vat() függvényre, mielőtt nekifog az új funkciónak?

(Nyílt kérdés – gondolkodj el a válaszon, mielőtt megnézed az útmutatót.)

Útmutató a jó válaszhoz:

  • Ha a fizetési logika módosítja az összegszámítást (akár véletlenül), a teszt azonnal jelzi
  • A teszt dokumentálja, hogyan viselkedik az ÁFA számítás most – ez referenciaként szolgál
  • Refaktoráláshoz „biztosítékot" ad, ha az ÁFA logikát is érinteni kell az új feature során

10. kérdés – Igaz, hamis, vagy kontextustól függ?

Értékeld az alábbi állításokat! Minden állításhoz válaszd: Igaz, Hamis, vagy Kontextustól függ – és indokold röviden.

  1. „Minden kódsort tesztelni kell."
  2. „Ha a tesztek zöldek, deploy-olhatok production-ba."
  3. „A tesztek lassítják a fejlesztést."
  4. „Jobb teszt nélkül kiszállítani, mint késni a tesztírással."

Útmutató:

  1. Hamis – Triviális getter/setter, eldobandó prototype, generált kód esetén felesleges overhead.
  2. Kontextustól függ – Zöld tesztek szükséges, de nem elégséges feltétel. A tesztek minőségétől, lefedettségétől és a deploy folyamattól is függ.
  3. Kontextustól függ – Rövid távon igen, mert több idő kell. Hosszú távon csökkentik a debuggolásra és hotfix-ekre fordított időt.
  4. Kontextustól függ – Kritikus üzleti logikánál a teszt nélküli deploy komoly kockázat. Prototípusnál, MVP kísérletnél ez lehet elfogadható kompromisszum – de tudatos döntésnek kell lennie, nem lustaságból.
Scroll to Top