在Python + pytest中实现页面对象模式

当我开始研究测试自动化时,我无法理解-“什么是Page Object以及如何在Python + pytest中实现它?”。 在研究互联网时,我发现了其他语言和框架的实现:我无法理解的教育文章。 因此,我决定编写此分析。 这个想法是用Python + pytest展示实现,并以一种可访问的语言对其进行解释。


什么是页面对象


这是一种流行的模式,是Web产品测试自动化中的事实上的标准。 基本思想是将测试逻辑与实现分开。


每个项目网页都可以描述为一个类对象。 用户交互以类方法描述,并且仅业务逻辑保留在测试中。 当更改Web应用程序的布局时,此方法有助于避免测试问题。 您只需要更正描述页面的类。


页面对象定义了以下部分:


  • 基页\基类-实现使用webdriver的必要方法。
  • Page Object \ Page Class-实现用于处理网页上元素的方法。
  • 测试-实现由测试用例的业务逻辑描述的测试。

页面对象模式的模式。
图片
为了清楚地说明该主题,我们实施了自动化测试。


实施的理论部分


步骤


  1. 用户打开浏览器;
  2. 用户在地址栏中输入https://ya.ru/
  3. 用户在搜索栏中输入单词“ Hello”。
  4. 用户单击“查找”按钮。

预期结果
用户被重定向到搜索。 搜索结果包含子项(视频,图片等)。


检查 :搜索页面上有一个导航栏,并且包含“图片”和“视频”元素。


实施的实际部分


要理解本文,您需要了解Python,OOP的基本结构,了解Selenium的原理和功能。


我们将使用以下库:硒和pytest。 您可以通过pip软件包管理器进行安装。


pip install selenium pip install pytest 

另外,请不要忘记为浏览器下载驱动程序。 本文使用chrome webdriver。 您可以在此处下载。 要使用它,请将文件放在项目的根目录中。


创建夹具


首先,您需要实现WebDriver的初始化。 我们将在装置中对其进行描述。 pytest中的装置是具有自己执行周期的函数。
这是unittest中SetUp和TearDown方法的替代替代品。 使用固定装置,您可以准备系统的初始状态以进行测试。


在pytest中,夹具文件的保留名称为conftest.py


我们创建conftest.py文件,并使用名称-浏览器实现该功能。


我们用@ pytest.fixture装饰器对其进行标记,然后将scope参数与session值一起传递。 这意味着该夹具功能将在每个测试会话中仅执行1次。


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

接下来,我们描述将在测试之前执行的部分。 它使用chromedriver的位置指示来初始化webdriver。 接下来,我们使用yield结构,该函数将功能分为多个部分-在测试之前和之后。


在“测试后”部分,我们调用quit函数,该函数结束会话并杀死webdriver实例。


基本页面


创建BaseApp.py文件。 在BasePage类中,我们定义了使用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) 

在BasePage类中,创建一个接受驱动程序的构造函数-webdriver的实例。 指定base_url,它将用于打开页面。


接下来,我们创建方法find_element(搜索一个元素并返回它)和find_elements(搜索集合并以列表形式返回)。


这是WebdriverWait的包装,后者负责Selenium中的明确期望。


在函数中,我们确定时间,默认情况下为10秒。 现在是时候搜索该物品了。 Go_to_site方法-从WebDriver调用get函数。 该方法使您可以转到指示的页面。 我们将base_url传递给它。


页面对象


我们的网页类在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 

我们创建类YandexSeacrhLocators。 它仅用于存储定位器。
在课堂上,我们描述了定位器:


LOCATOR_YANDEX_SEARCH_FIELD-搜索字符串定位器
LOCATOR_YANDEX_SEARCH_BUTTON-“查找”按钮的定位器
LOCATOR_YANDEX_NAVIGATION_BAR-导航栏定位器(图片,视频等)


创建一个从BasePage继承的SearchHelper类。


我们实现用于搜索的辅助方法:
enter_word-搜索搜索字符串的元素,单击并输入所需的单词到搜索中;
click_on_the_search_button-搜索搜索按钮的元素并单击它;
check_navigation_bar-搜索导航项并获取text属性。 创建一个列表并按条件过滤。 如果字符串长度大于零,则将该项目添加到列表中。 例如,将默认时间重新设置为2秒。


测验


 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 

我们创建测试功能test_yandex_seacrh,它将接受浏览器固定装置。 接下来,第一行创建页面对象-yandex_main_page。 从对象中,我们调用与页面元素进行交互的方法。 该功能描述了用户操作的顶级逻辑。


让我们将实现的所有内容都转移到该方案中,类似于Page Object方案。 重命名文章中文件名下的块。


图片


如您所见,我们能够将模式付诸实践。


我将保留指向完成的存储库的链接。 感谢您的阅读!

Source: https://habr.com/ru/post/zh-CN472156/


All Articles