Tanuld meg, hogyan teszteld a Python-feladataidat az Exercism-ön.
A weboldalunk tesztfuttatójaként a pytest eszközt használjuk.
Ha a Python-kurzus feladatainak tesztjeit helyben szeretnéd letölteni és futtatni, telepítened kell a pytest csomagot a fejlesztői gépedre.
Érdemes a következő pytest bővítményeket is telepítened:
Javasoljuk továbbá a pylint kódellenőrző program használatát, mivel része a weboldalon adott automatikus visszajelzésnek, és nagyon hasznos statikus elemzőeszköz lehet.
A kényelmes használat érdekében a pytest pytest-pylint bővítményével a pylint-et a pytest segítségével futtathatod a parancssorból.
A Pylint beállítása kicsit sok lehet, ezért az oktatóanyag a pylint.readthedocs.io oldalról segíthet az indulásban, ahogy a Real Python Kódminőség: eszközök és bevált gyakorlatok áttekintése is.
A Pytest a Python beépített pip segédprogramjával telepíthető és frissíthető.
További tippekért Brett Cannon remek gyors és egyszerű útmutatót írt arról, hogyan telepíts csomagokat Pythonhoz, valamint egy nagyszerű magyarázatot is arról, miért a python -m pip-et érdemes használni.
A Python parancssori argumentumairól bővebben lásd a Python dokumentációjának parancssor és környezet szakaszát.
Megjegyzés: A Python3 és a py a te rendszereden lehet, hogy a Python aliasa, de az is lehet, hogy nem.
A lenti telepítési parancsokat ennek megfelelően igazítsd hozzá.
Ha virtuális környezetbe telepíted a pytest-et, a parancsok futtatása előtt győződj meg róla, hogy a környezet be van aktiválva.
Ellenkező esetben a pytest telepítése globális lesz.
PS C:\Users\foobar> py -m pip install pytest pytest-cache pytest-subtests pytest-pylint
Successfully installed pytest-8.3.3 ...
$ python3 -m pip install pytest pytest-cache pytest-subtests pytest-pylint
Successfully installed pytest-8.3.3 ...
A telepítés sikerességének ellenőrzéséhez:
$ python3 -m pytest --version
pytest 8.3.3
A tesztek futtatásához a terminálban a cd parancs segítségével lépj be abba a mappába, ahol a feladat található (a lenti <exercise-folder-location> helyére írd a saját elérési utadat).
$ cd <exercise-folder-location>
<exercise-folder-location> or most things inside angle brackets denote a placeholder value.
A normal path or file name should be written without any brackets.
For example: /Users/janedoe/exercism/python/exercises/concept/chaitanas-colossal-coaster (on *nix systems), C:\Users\janedoe\exercism\python\exercises\practice\hello-world\ (on Windows), myFolder or my_file.py.
A futtatni kívánt fájl neve általában _test.py végződésű.
Ez a fájl tartalmazza a feladat megoldásához tartozó teszteket, és ugyanazok a tesztek futnak le a weboldalon is, amikor feltöltesz egy megoldást.
Ezután futtasd a következő parancsot a terminálban, és a <exercise_test.py> helyére írd a tesztfájl elérési útját/nevét:
$ python3 -m pytest -o markers=task <exercise_test.py>
==================== 7 passed in 0.08s ====================
Ha a fenti parancsban nem használod a pytest -o markers=task beállítást, előfordulhat, hogy warnings üzeneteket kapsz „unknown markers” szöveggel, amikor egy olyan tesztet futtatsz, amely az új szintaxisunkat használja.
Hogy ne kelljen minden egyes tesztfuttatásnál beírnod a pytest -o markers=task parancsot, használhatsz egy pytest.ini konfigurációs fájlt, amely a Python-kurzus könyvtárának legfelső szintjéről tölthető le: pytest.ini.
Saját pytest.ini fájlt is létrehozhatsz a következő tartalommal:
[pytest]
markers =
task: A concept exercise task.
Ha ezt a fájlt az Exercism-feladatok gyökér- vagy munkakönyvtárába helyezed el, regisztrálja a markereket, és megszűnnek a figyelmeztetések.
A pytest markereiről bővebb információt a pytest dokumentációjában a tesztfüggvények megjelölése és az egyedi markerekkel való munka című részben találsz.
A pytest-konfigurációk testreszabásáról bővebb információt a pytest dokumentációjában, a konfigurációs fájlformátumok című részben találsz.
Amikor egy teszt elbukik, a pytest kiírja a terminálra minden sikertelen teszt szövegét, valamint az egyes tesztek várt és tényleges return értékét.
Alább egy általános példa egy sikertelen tesztre:
$(my_venv) python3 -m pytest -o markers=task <exercise_test.py>
=================== FAILURES ====================
______________ name_of_failed_test ______________
# Test code inside of <exercise_test.py> that failed.
...
E TypeOfError: ReturnedValue != ExpectedValue
exercise_test.py:<line_of_failed_test>: TypeOfError
============ short test summary info ============
FAILED exercise_test.py::ExerciseTest::name_of_failed_test
========== 1 failed, 2 passed in 0.13s ==========
Ha pontosan szabályozni szeretnéd, mit ír ki a pytest a képernyőre, íme néhány hasznos parancssori argumentum, amelyekkel testre szabhatod a működését.
-v]A -v (verbose) kapcsoló hozzáadásával a sikertelen tesztek mellett a környezeti információkat és a tesztek összegzését is megjeleníted:
$(my_venv) python3 -m pytest -o markers=task -v exercises/<exercise_name>/<test_file_test.py>
======================================== test session starts ===========================================
platform darwin -- Python 3.9.0, pytest-6.2.5, -- /usr/local/envs/my_env/bin/python3
cachedir: .pytest_cache
metadata: {'Python': '3.9.0', 'Platform': 'macOS-10.14.6-x86_64-i386-64bit', 'Packages': {'pytest': '6.2.1'}, 'Plugins': {'subtests': '0.5.0', 'pylint': '0.18.0'}
rootdir: /Users/<user>/exercism/python, configfile: pytest.ini
plugins: subtests-0.5.0, pylint-0.18.0
collected 5 items
exercises/exercise-name/exercise_file_test.py::ExerciseNameTest::test_one FAILED [ 20%]
exercises/exercise-name/exercise_file_test.py::ExerciseNameTest::test_two FAILED
exercises/exercise-name/exercise_file_test.py::ExerciseNameTest::test_three PASSED [ 40%]
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_four FAILED
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_five PASSED [ 60%]
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_six FAILED
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_seven PASSED [ 80%]
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_eight FAILED
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_nine PASSED [100%]
================================================ FAILURES ======================================================
# Failed tests are then individually printed out below
.......
-x]A -x kapcsolóval a tesztek a szokásos módon futnak le, de a futtatás az első sikertelen tesztnél leáll.
Ez akkor segít, ha egyszerre csak egy részfeladatot vagy egyetlen teszt hibáját szeretnéd kinyomozni:
$(my_venv) python3 -m pytest -o markers=task -x exercises/<exercise_name>/<test_file_test.py>
=================== FAILURES ====================
_______________ example_test_foo ________________
...
...
============ short test summary info ============
FAILED example_test.py::ExampleTest::example_test_foo
!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!
========== 1 failed, 5 passed in 0.28s ==========
--ff]A pytest-cache bővítmény megjegyzi, mely tesztek buktak el legutóbb, amikor a pytest-et futtattad, így a --ff kapcsoló hatására a pytest először a korábban sikertelen teszteket futtatja le, majd a többi teszttel folytatja.
Ez felgyorsíthatja a tesztelést, ha sok apró javítást végzel egy adott részfeladat vagy bemenet körül.
$(my_venv) python3 -m pytest -o markers=task --ff <example_file_test.py>
==================== 7 passed in 503s ====================
Javasoljuk a következő parancsokat, amelyek megkönnyítik és (talán) felgyorsítják a hibakeresést:
Először válts át a tesztelni kívánt feladat könyvtárába:
$(my_venv) cd path/to/exercise
Ezután futtasd a teszteket a korábban ismertetett -x és --ff argumentumokkal:
$(my_venv) python3 -m pytest -o markers=task -x --ff <example_file_test.py>
Ez lefuttatja a megoldásod tesztjeit.
Amikor a pytest sikertelen tesztbe ütközik, a program leáll, és megmondja, melyik teszt bukott el.
Amikor javítasz, és újra lefuttatod a tesztet, a pytest először a korábban elbukott tesztet futtatja le, majd folytatja a többi teszttel.
Ha profiként szeretnél hibát keresni, a pytest parancs után használhatod a --pdb argumentumot, és beugorhatsz a beépített Python hibakeresőbe, a PDB-be.
$(my_venv) python3 -m pytest -o markers=task -x --ff --pdb <example_file_test.py>
=============== 4 passed in 0.15s ===============
Amikor egy teszt elbukik, a PDB-be beugorva lépésenként haladhatsz végig a kódodon, miközben az aktuális scope-ot látod, és megnézheted a változók értékét, valamint a különböző függvények szignatúráját.
A PDB modulról bővebb részleteket a Python PDB-dokumentációjában találsz.
Ezenkívül a pytest PDB-ről szóló dokumentációja és ez az útmutató a Real Pythontól rendkívül hasznos.
Ha szeretnéd az IDE-det olyan eszközökkel bővíteni, amelyek segítenek a kódod tesztelésében és fejlesztésében, nézd meg az eszközök oldalt. Ott több IDE-t, szerkesztőt és néhány hasznos bővítményt is bemutatunk a linteléshez és a hibakereséshez.
Megjegyzés: Ha Windowson a PSF Installer segítségével telepítetted a Pythont, akkor a parancs py lesz a python3 helyett.
Egy kicsit idegesítő lehet minden egyes modulfuttatásnál beírni, hogy python3 -m.
Ezt elkerülheted, ha a Python-telepítésed Scripts mappáját hozzáadod a PATH-hoz.
Ha nem tudod, hová telepítetted a Pythont, futtasd a következő parancsot a terminálban:
$ python3 -c "import os, sys; print(os.path.dirname(sys.executable))"
<python_directory>
A visszaadott könyvtár az, ahová az éppen aktív Python-verziód telepítve van; ebben a szakaszban <python_directory> néven hivatkozunk rá.
Kattints a Windows Start gombra, keresd meg az Edit the system environment variables elemet, és nyomj Entert.
Ezután nyomd meg az Environment Variables... gombot:

Ezután keresd meg a Path változót a User variables listában, jelöld ki, és kattints az Edit... gombra:

Ezután adj hozzá egy új sort a képen látható módon, a <python_directory> helyére pedig írd a Python-telepítésed könyvtárát:

Az alábbiak a legtöbb Linux- és MacOS-változaton működnek bash shell esetén.
A parancsok Linux-disztribúciónként, valamint attól függően is eltérhetnek, hogy fish vagy zsh shellt használsz.
A <python_directory> helyére a python3 -c "import os, sys; print(os.path.dirname(sys.executable))" parancs kimenetét írd.
export PATH="$PATH:<python_directory>"