[[oktatas:programozás:python|< Python]]
====== TDD ======
* **Szerző:** Sallai András
* Copyright (c) 2020, Sallai András
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]]
* Web: https://szit.hu
===== A TDD =====
A **TDD** a **Test-Driven Development** rövidítése. Magyarul **teszt vezérelt fejlesztés**.
- TDD esetén a teszt fejlesztésével kezdem. De csak annyit fejlesztek rajta, hogy éppen ne teljesüljön. Első körben, annyi is elég, hogy egy nem létező osztályra hivatkozunk.
- Ezek után minimálisan, annyit fejlesztünk az ipari kódon (hasznos kód), ami teljesíti a tesztet, de nem többet. Futtatjuk a tesztet. Ha teljesül mehetünk tovább.
- Megnézzük mit lehet az ipari kódban, és a teszt kódban újratervezni (refactor). Ha találunk valamit, lekódoljuk, majd futtatjuk a tesztet. Ha teljesült, mehetünk vissza az első lépéshez, vagyis fejlesztjük a tesztet.
===== Példa =====
==== Iteráció 01 ====
=== Teszt fejlesztése ===
Írjunk egy tesztet amely betölti a Haromszog osztályt, amikor az még nem is
létezik:
import haromszog
haromszog.Haromszog()
Futtassuk a tesztet. A teszt elszáll, mivel nem létezik a triangle fájl.
=== Ipari kód fejlesztése ===
Most annyi kódot írjunk, ami teljesíti a tesztet.
class Haromszog():
pass
Futtassuk a tesztet. A teszt teljesül.
=== Újraépítés ===
Lehet jobb lenne angol elnevezésekkel.
from triangle import Triangle
class Triangle():
pass
==== Iteráció 02 ====
=== Teszt fejlesztése ===
Most fejlesszük a tesztet, addig, amíg meghívja a Triangle
osztályban a calcArea() függvényt.
from triangle import Triangle
def testCalcAreaExist():
Triangle.calcArea()
testCalcAreaExist()
Most futtassuk a tesztet. A teszt elbukik, mivel még nem létezik
a Triangle osztályban calcArea() függvény.
=== Ipari kód fejlesztése ===
Most fejlesszünk annyit a Triagnle osztályon, hogy teljesüljön a teszt.
class Triangle():
def calcArea():
pass
Futtassuk a tesztet. A teszt most teljesül.
=== Újraépítés ===
A teszt számára is készíthetünk osztályt:
from triangle import Triangle
import unittest
class TestTriangle(unittest.TestCase):
def testCalcAreaExist(self):
Triangle.calcArea()
if __name__ == "__main__":
unittest.main()
A if __name__ == "__main__": sor kötelező a
a TestCase osztály indításához.
==== Iteráció 03 ====
=== Teszt fejlesztése ===
Fejlesszük a tesztet. A calcArea() függvényhívásnál adjunk át egy
alapot, legyen ez most 30.
class TestTriangle(unittest.TestCase):
def testCalcAreaExist(self):
Triangle.calcArea(30)
if __name__ == "__main__":
unittest.main()
Teszteljünk. A teszt elbukik, mivel a calcArea() függvény nem fogad semmilyen
paramétert.
=== Ipari kód fejlesztése ===
Fejlesszük a calcArea() függvényt addig, hogy elfogadja a base paramétert.
class Triangle():
def calcArea(base):
pass
Futtassuk a tesztet. A teszt teljesül.
=== Újraépítés ===
class TestTriangle(unittest.TestCase):
def testCalcAreaOneParameter(self):
Triangle.calcArea(30)
if __name__ == "__main__":
unittest.main()
==== Iteráció 04 ====
=== Teszt fejlesztése ===
Fejlesszük a tesztet. Adjuk át a magasság értéket is a calcArea() függvénynek.
Futtassuk a tesztet. A teszt elbukik, mert csak egy paramétert fogad a függvény.
class TestTriangle(unittest.TestCase):
def testCalcAreaOneParameter(self):
Triangle.calcArea(30, 35)
if __name__ == "__main__":
unittest.main()
Futtassuk a tesztet. A teszt elbukik.
=== Ipari kód fejlesztése ===
Fejlesszük a calcArea() függvényt, amíg teljesíti a tesztet.
class Triangle():
def calcArea(b, h):
pass
Futtassuk a tesztet. A teszt teljesül.
=== Újraépítés ===
class TestTriangle(unittest.TestCase):
def testCalcAreaTwoParameter(self):
Triangle.calcArea(30, 35)
if __name__ == "__main__":
unittest.main()
class Triangle():
def calcArea(base, height):
pass
==== Iteráció 05 ====
=== Teszt fejlesztése ===
Fejlesszük a tesztet. A calcArea() függvénytől elvárjuk, hogy
adja vissza az alapból és magasságból kiszámolt 525.0 értéket.
Vizsgáljuk meg, hogy a megfelelő értéket kaptuk-e.
from triangle import Triangle
import unittest
class TestTriangle(unittest.TestCase):
def testCalcAreaTwoParameter(self):
area = Triangle.calcArea(30, 35)
self.assertEqual(area, 525.0, 'Az elvárt érték 525.0')
if __name__ == "__main__":
unittest.main()
Futtassuk a tesztet. A teszt elbukik.
=== Az ipari kód fejlesztése ===
Fejlesszük a függvényt addig, hogy visszaadja a 525.0 értéket.
class Triangle():
def calcArea(base, height):
return 525.0
Futtassuk a tesztet. Teljesült.
=== Újraépítés ===
class TestTriangle(unittest.TestCase):
def testCalcAreaNormalParameter(self):
area = Triangle.calcArea(30, 35)
self.assertEqual(area, 525.0, 'Az elvárt érték 525.0')
if __name__ == "__main__":
unittest.main()
==== Iteráció 06 ====
=== Teszt fejlesztése ===
Fejlesszük a tesztet. A calcArea() függvénynek más bemenő paraméterek
mellett is helyes értéket kell visszaadnia. Legyenek a bemenő
paraméterek most 52 és 48. Ekkor 1248-t kell kapnunk.
Ezt egy újabb függvényben írjuk meg a teszten belül.
from triangle import Triangle
import unittest
class TestTriangle(unittest.TestCase):
def testCalcAreaNormalParameter(self):
area = Triangle.calcArea(30, 35)
self.assertEqual(area, 525.0, 'Az elvárt érték 525.0')
def testCalcAreaNormalParameter2(self):
area = Triangle.calcArea(52, 48)
self.assertEqual(area, 1248.0, 'Az elvárt érték 1248.0')
if __name__ == "__main__":
unittest.main()
Futtassuk a tesztet. Az első teszt teljesül, de a második elbukik.
=== Az ipari kód fejlesztése ===
Fejlesszük tovább az ipari kódot, amíg teljesül mindkét teszt.
class Triangle():
def calcArea(base, height):
area = base*height/2
return area
Futtassuk a tesztet. A teszt teljesül.
=== Újraépítés ===
class Triangle():
def calcArea(base, height):
return base*height/2
==== Iteráció 07 ====
=== Teszt fejlesztése ===
Fejlesszük a tesztet. A programunk negatív szám esetén
adjon vissza -1-t.
from triangle import Triangle
import unittest
class TestTriangle(unittest.TestCase):
def testCalcAreaNormalParameter(self):
area = Triangle.calcArea(30, 35)
self.assertEqual(area, 525.0, 'Az elvárt érték 525.0')
def testCalcAreaNormalParameter2(self):
area = Triangle.calcArea(52, 48)
self.assertEqual(area, 1248.0, 'Az elvárt érték 1248.0')
def testCalcAreaNegative(self):
area = Triangle.calcArea(-5, 48)
self.assertEqual(area, -1, 'Az elvárt érték -1')
Futtassuk a tesztet. A teszt elbukik.
=== Az ipari kód fejlesztése ===
Fejlesszük az ipari kódot, amíg teljesül teszt.
class Triangle():
def calcArea(base, height):
if base < 0:
return -1
else:
return base*height/2
=== Újraépítés ===
class Triangle():
def calcArea(base, height):
if base < 0 or height < 0:
return -1
else:
return base*height/2