Implémentation du modèle d'objet de page en Python + pytest

Quand j'ai commencé à étudier l'automatisation des tests, je ne pouvais pas comprendre - «qu'est-ce que Page Object et comment l'implémenter en Python + pytest?». En étudiant Internet, j'ai trouvé une implémentation dans d'autres langages et frameworks: des articles pédagogiques qui m'étaient incompréhensibles. J'ai donc décidé d'écrire cette analyse. L'idée est de montrer l'implémentation en Python + pytest et de l'expliquer dans un langage accessible.


Qu'est-ce qu'un objet de page


Il s'agit d'un modèle populaire qui est la norme de facto dans l'automatisation des tests de produits Web. L'idée de base est de séparer la logique de test de l'implémentation.


Chaque page Web de projet peut être décrite comme un objet de classe. L'interaction utilisateur est décrite dans les méthodes de classe et seule la logique métier reste dans les tests. Cette approche permet d'éviter les problèmes de tests lors de la modification de la présentation d'une application Web. Vous devez corriger uniquement la classe qui décrit la page.


L'objet Page définit les parties:


  • Page de base \ Classe de base - ImplĂ©mente les mĂ©thodes nĂ©cessaires pour travailler avec le pilote Web.
  • Page Object \ Page Class - ImplĂ©mente des mĂ©thodes pour travailler avec des Ă©lĂ©ments sur des pages Web.
  • Tests - ImplĂ©mente les tests dĂ©crits par la logique mĂ©tier du scĂ©nario de test.

Schéma du modèle d'objet de page.
image
Pour expliquer clairement le sujet, nous implémentons un test automatisé.


La partie théorique de la mise en œuvre


Étapes :


  1. L'utilisateur ouvre un navigateur;
  2. L'utilisateur entre https://ya.ru/ dans la barre d'adresse;
  3. L'utilisateur entre le mot «Bonjour» dans la barre de recherche;
  4. L'utilisateur clique sur le bouton «Rechercher».

RĂ©sultat attendu :
L'utilisateur est redirigé vers la recherche. Les résultats de la recherche comportent des sous-éléments (vidéo, photos, etc.).


Vérifiez : sur la page de recherche, il y a une barre de navigation et des éléments «image» et «vidéo».


La partie pratique de la mise en Ĺ“uvre


Pour comprendre l'article, vous devez connaître les constructions de base de Python, OOP, comprendre les principes et les fonctions de Selenium.


Nous utiliserons les bibliothèques: sélénium et pytest. Vous pouvez les installer via le gestionnaire de packages pip.


pip install selenium pip install pytest 

N'oubliez pas non plus de télécharger le pilote pour le navigateur. Cet article utilise un pilote Web Chrome. Vous pouvez le télécharger ici . Pour l'utiliser, placez le fichier dans le répertoire racine du projet.


Créer un appareil


Vous devez d'abord implémenter l'initialisation pour WebDriver. Nous le décrirons dans les luminaires. Les fixtures dans pytest sont des fonctions qui ont leur propre périodicité d'exécution.
Il s'agit d'un remplacement alternatif pour les méthodes SetUp et TearDown dans unittest. À l'aide d'appareils, vous pouvez préparer l'état initial du système pour les tests.


Dans pytest il y a un nom réservé pour le fichier de fixture - conftest.py .


Nous créons le fichier conftest.py et implémentons la fonction avec le nom - navigateur.


Nous le marquons avec le décorateur @ pytest.fixture et passons le paramètre scope avec une valeur de session. Cela signifie que cette fonction de fixture ne sera exécutée qu'une seule fois par session de test.


 import pytest from selenium import webdriver @pytest.fixture(scope="session") def browser(): driver = webdriver.Chrome(executable_path="./chromedriver") yield driver driver.quit() 

Ensuite, nous décrivons la partie qui sera exécutée avant les tests. Il initialise le pilote Web avec une indication de l'emplacement du pilote chromé. Ensuite, nous utilisons la construction yield, qui divise la fonction en parties - avant les tests et après les tests.


Dans la partie «après les tests», nous appelons la fonction quit, qui termine la session et tue l'instance de webdriver.


Page de base


Créez le fichier BaseApp.py. Dans la classe BasePage, nous définissons les méthodes de base pour travailler avec WebDriver.


 from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class BasePage: def __init__(self, driver): self.driver = driver self.base_url = "https://ya.ru/" def find_element(self, locator,time=10): return WebDriverWait(self.driver,time).until(EC.presence_of_element_located(locator), message=f"Can't find element by locator {locator}") def find_elements(self, locator,time=10): return WebDriverWait(self.driver,time).until(EC.presence_of_all_elements_located(locator), message=f"Can't find elements by locator {locator}") def go_to_site(self): return self.driver.get(self.base_url) 

Dans la classe BasePage, créez un constructeur qui accepte un pilote - une instance de webdriver. Spécifiez base_url, qui sera utilisé pour ouvrir la page.


Ensuite, nous créons les méthodes find_element (recherche un élément et le renvoie) et find_elements (recherche l'ensemble et retourne sous forme de liste).


Il s'agit d'un wrapper sur WebdriverWait, qui est responsable des attentes explicites dans Selenium.


Dans la fonction, nous déterminons le temps, qui est par défaut de 10 secondes. C'est le moment de rechercher l'article. Méthode Go_to_site - Appelle la fonction get depuis WebDriver. La méthode vous permet d'accéder à la page indiquée. Nous lui passons base_url.


Objet de page


Notre classe de page Web est implémentée dans le fichier YandexPages.py.


 from BaseApp import BasePage from selenium.webdriver.common.by import By class YandexSeacrhLocators: LOCATOR_YANDEX_SEARCH_FIELD = (By.ID, "text") LOCATOR_YANDEX_SEARCH_BUTTON = (By.CLASS_NAME, "search2__button") LOCATOR_YANDEX_NAVIGATION_BAR = (By.CSS_SELECTOR, ".service__name") class SearchHelper(BasePage): def enter_word(self, word): search_field = self.find_element(YandexSeacrhLocators.LOCATOR_YANDEX_SEARCH_FIELD) search_field.click() search_field.send_keys(word) return search_field def click_on_the_search_button(self): return self.find_element(YandexSeacrhLocators.LOCATOR_YANDEX_SEARCH_BUTTON,time=2).click() def check_navigation_bar(self): all_list = self.find_elements(YandexSeacrhLocators.LOCATOR_YANDEX_NAVIGATION_BAR,time=2) nav_bar_menu = [x.text for x in all_list if len(x.text) > 0] return nav_bar_menu 

Nous créons la classe YandexSeacrhLocators. Ce ne sera que pour stocker des localisateurs.
Dans la classe, nous décrivons les localisateurs:


LOCATOR_YANDEX_SEARCH_FIELD - localisateur de chaîne de recherche
LOCATOR_YANDEX_SEARCH_BUTTON - localisateur du bouton "Rechercher"
LOCATOR_YANDEX_NAVIGATION_BAR - localisateur de barre de navigation (photos, vidéos, etc.)


Créez une classe SearchHelper, héritez de BasePage.


Nous implémentons des méthodes auxiliaires pour travailler avec la recherche:
enter_word - recherche un élément de la chaîne de recherche, clique et entre le mot souhaité dans la recherche;
click_on_the_search_button - Recherche un élément du bouton de recherche et clique dessus;
check_navigation_bar - Recherche des éléments de navigation et obtient l'attribut text. Crée une liste et filtre par condition. Si la longueur de la chaîne est supérieure à zéro, ajoute alors l'élément à la liste. Par exemple, redéfinissez l'heure par défaut en la définissant sur 2 secondes.


Les tests


 from YandexPages import SearchHelper def test_yandex_search(browser): yandex_main_page = SearchHelper(browser) yandex_main_page.go_to_site() yandex_main_page.enter_word("Hello") yandex_main_page.click_on_the_search_button() elements = yandex_main_page.check_navigation_bar() assert "" and "" in elements 

Nous créons la fonction de test test_yandex_seacrh, qui acceptera le montage du navigateur. Ensuite, la première ligne crée l'objet page - yandex_main_page. De l'objet, nous appelons les méthodes d'interaction avec les éléments de page. La fonction décrit la logique de niveau supérieur des actions utilisateur.


Transférons tout ce que nous avons implémenté dans le schéma, similaire au schéma Page Object. Renommez les blocs sous le nom des fichiers de l'article.


image


Comme vous pouvez le voir, nous avons pu mettre le modèle en pratique.


Je vais laisser un lien vers le référentiel terminé. Merci d'avoir lu!

Source: https://habr.com/ru/post/fr472156/


All Articles