====== Python web test amb Pytest ====== {{ pytest_logo.svg?200|By Holger Krekel - https://pypi.org/project/pytest/, CC BY 2.5, https://commons.wikimedia.org/w/index.php?curid=116199948 }} Referències: * Continua de [[Python Web]] , cal conèixer Flask * Necessitaràs [[Python venv]] {{tag> #Daw #DawMpDual #DawMpProj #DawMp07Uf1 #DawMp07Uf02 #DawMp07Uf03 #DawMp07Uf04 #DawMp07Uf1 #DawMp07Uf02 #DawMp07Uf03 #DawMp07Uf04 #Ciber #CiberMp03 #Ceti #CetiMp03 python web flask test testing pytest }} \\ Per poder seguir els exemples d'aquesta pàgina cal que abans hagis fet l'app bàsica amb el formulari que apareix a [[Python web]]. ===== Pytest + client de tests de Flask ===== En aquesta primera aproximació **testejarem la webapp Flask amb un client intern de ''pytest'', és a dir, que no farà servir un //browser// real**. Fem-li un cop d'ull a la [[https://flask.palletsprojects.com/testing/|documentació de test amb Flask]]. Primera cosa que cal fer, instal·lar el mòdul de tests ''pytest'': (env) $ pip install pytest Després, ens diuen que fem un **test skeleton**, però l'exemple que ens donen té una configuració avançada per posar a punt la base de dades, utilitzant una //app factory//, etc. Nosaltres implementarem una versió simplificada sobre l'arxiu ''test_web.py''. Com podeu veure, **Flask disposa d'un client ''test_client''** que permet accedir als //endpoints// o rutes i comprovar els continguts rebuts mitjançant **assert**: import pytest from web import app @pytest.fixture def client(): with app.test_client() as client: yield client def test_landing_page(client): rv = client.get('/') assert b'Hello, World' in rv.data Correm els tests amb la comanda ''pytest'': (env) $ pytest ============================ test session starts ============================= platform linux -- Python 3.8.10, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 rootdir: /home/enric/dev21/basicflask collected 1 item test_web.py . [100%] ============================= 1 passed in 0.09s ============================== Com podem veure, ''pytest'' posa en marxa els tests dels arxius que comencen per ''test_'', i dins d'aquests, corre les funcions que també comencin per ''test_''. \\ ===== Pytest amb Selenium ===== [[Selenium]] és una llibreria per automatitzar la utilització d'un //browser// real. Primer caldrà que instal·lem el package de pytest-selenium: (env) $ pip install pytest-selenium I també el driver per a automatitzar el Firefox: $ sudo apt install firefox-geckodriver Documentacions importants: * [[https://pytest-selenium.readthedocs.io/en/latest/user_guide.html|Doc oficial de pytest-selenium]]. * [[https://selenium-python.readthedocs.io/|Doc oficial python-selenium]] Posem aquí un test doble fonamental: * A la //home page// comprovem que el text que apareix contingui "Hello, World" * Al formulari d'exemple realitzat a [[Python Web]] utilitzem ''send_keys'' per escriure al camp de text i enviem el formulari localitzant el ''submit'' i clicant-lo. import pytest from selenium.webdriver.common.by import By def test_home(selenium): selenium.get('http://localhost:5000') # podem examinar el què ens retorna el browser a "page_source" assert "Hello, World" in selenium.page_source def test_form(selenium): # carreguem la pàgina del formulari selenium.get('http://localhost:5000/formulari') # busquem el quadre de text i hi escrivim un nom elem = selenium.find_element(By.TAG_NAME,"input") elem.send_keys("manolo") # cerquem el botó de submit i el cliquem submit = selenium.find_element(By.XPATH,"//input[@type='submit']") submit.click() # comprovem que el missatge de salutació contingui # el nom introduit prèviament al formulari assert "Salut, manolo" in selenium.page_source Per posar en marxa el test ens caldrà 2 shells. En la 1a, posem en marxa la app: (env) $ flask --app web run I a la 2a shell engeguem els tests: (env) $ pytest --driver Firefox Fixa't en què per trobar elements fem servir ''find_element'' amb un ''By.XPATH''. Pots trobar més info de com localitzar elements a la **doc oficial de Selenium per Python**: * [[https://selenium-python.readthedocs.io/navigating.html|Secció Navigating]] * [[https://selenium-python.readthedocs.io/api.html#locate-elements-by|Secció API]] \\ ===== Exercici : login ===== Pàgina de login de l'app: * Crea un formulari que demani usuari i contrasenya. El formulari s'accedeix per mètode GET però envia les dades per mètode POST. * Crea una pàgina (per POST) que respongui al formulari d'usuari i contrasenya. Crea un diccionari global amb noms d'usuari i contrasenyes vàlids (//hardcoded//). * Assegura't que la pàgina de resposta al formulari respon amb un missatge que contingui un "OK" a la pàgina, i si el nom d'usuari és erroni respon adequadament amb un missatge que contingui "ERROR". * **Comprova manualment el punt anterior. Abans de fer els tests automàtics cal fer-los manuals PER A TOTS ELS CASOS** (tant si funciona OK, com si dona error). Testejant l'app. * Examina [[https://flask.palletsprojects.com/en/1.1.x/testing/#logging-in-and-out|la secció "logging in and out" de la documentació dels tests]]. * Afegeix dues funcions de test que comprovin el següent: - Que els usuaris i contrasenyes que has //hardcodejat// al codi es loguen correctament. - Que una combinació usuari/contrasenya que no ha estat introduïda no funciona i dona el missatge d'error. \\ ===== Per saber més ===== En [[https://testdriven.io/blog/flask-pytest/|aquesta pàgina s'expliquen molts conceptes de testing en Flask i pytest]].