当今的软件开发越来越倾向于敏捷式的开发模式,这需要测试工作能够跟上节奏,快速响应并且高效稳定。针对这种需求,我们使用POM(Page Object Model)和Selenium自动化框架封装来实现自动化测试。
视频教程:突破测试瓶颈,进入大厂跳槽涨薪!POM+Selenium自动化框架封装实战教程_哔哩哔哩_bilibili
一、POM模型介绍
Page Object Model是一种测试设计模式,它将页面元素和页面动作抽象成一个个独立的类,通过调用这些类的方法来进行测试操作。这样做可以让测试代码更易读、更易维护,而且可以避免多处代码冗余。
我们来看看下面这个简单的登录页面的示例:
在这个页面中,我们可以通过输入用户名、密码和点击登录按钮来进行登录操作。那么我们就可以通过POM模型来抽象出3个独立的类:LoginPage、UserNameField、PasswordField以及LoginButton。
python
# UserNameField.py
class UserNameField(object):
def __init__(self, driver):
self.driver = driver
self.username_field_locator = "id=username"
def input_username(self, username):
self.driver.find_element_by_id(self.username_field_locator).send_keys(username)
# PasswordField.py
class PasswordField(object):
def __init__(self, driver):
self.driver = driver
self.password_field_locator = "id=password"
def input_password(self, password):
self.driver.find_element_by_id(self.password_field_locator).send_keys(password)
# LoginButton.py
class LoginButton(object):
def __init__(self, driver):
self.driver = driver
self.login_button_locator = "xpath=//button[@type='submit']"
def click_login_button(self):
self.driver.find_element_by_xpath(self.login_button_locator).click()
# LoginPage.py
class LoginPage(object):
def __init__(self, driver):
self.driver = driver
# 实例化其他三个类的对象
self.username = UserNameField(driver)
self.password = PasswordField(driver)
self.login_button = LoginButton(driver)
def login(self, username, password):
self.username.input_username(username)
self.password.input_password(password)
self.login_button.click_login_button()
这样,我们就完成了对登录页面元素和操作的抽象。在测试代码中,我们只需要调用LoginPage类的login方法即可。
# test_login.py
import unittest
from selenium import webdriver
from LoginPage import LoginPage
class TestLogin(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.driver.get("http://example.com/login")
def test_login_valid_credentials(self):
login_page = LoginPage(self.driver)
login_page.login("username", "password")
assert "Welcome!" in self.driver.page_source
@classmethod
def tearDownClass(cls):
cls.driver.quit()
二、Selenium自动化框架封装
Selenium是常用的Web应用程序自动化测试工具,它支持多种浏览器和平台,并提供了丰富的API来操作页面元素,包括查找元素、输入文本、点击按钮等等。但是,在使用Selenium时,我们需要编写很多重复的代码,比如查找元素、判断元素是否存在等等。为了解决这个问题,我们可以封装一些常用的操作,以便于测试人员更加专注于测试用例的实现。
我们可以通过继承Selenium WebElement类来实现元素操作的封装:
# BasePage.py
from selenium.webdriver.remote.webelement import WebElement
class BasePage(object):
def __init__(self, driver):
self.driver = driver
def is_element_present(self, locator):
try:
self.driver.find_element(*locator)
except:
return False
return True
class PageElement(WebElement):
def __init__(self, context, by, value):
self.context = context
self.by = by
self.value = value
super(PageElement, self).__init__(parent=context, id_=None)
def find_element(self, *args):
return self.context.find_element(*args)
def find_elements(self, *args):
return self.context.find_elements(*args)
def __get__(self, instance, owner):
if instance is None:
return self
else:
element = self.context.find_element(self.by, self.value)
return element
class BasePageObject(BasePage):
def __init__(self, driver):
super(BasePageObject, self).__init__(driver)
def wait_for_element_to_be_present(self, locator, timeout=10):
WebDriverWait(self.driver, timeout).until(EC.presence_of_element_located(locator))
def wait_for_element_to_disappear(self, locator, timeout=10):
WebDriverWait(self.driver, timeout).until_not(EC.presence_of_element_located(locator))
在BasePage中,我们定义了is_element_present方法,用于判断元素是否存在。在PageElement中,我们继承了Selenium WebElement类,并重写了find_element和find_elements方法,以便于后面调用元素的操作。在BasePageObject中,我们定义了wait_for_element_to_be_present方法和wait_for_element_to_disappear方法,用于等待元素出现或消失。
接下来,我们可以使用这些封装好的方法来编写测试用例:
# test_login.py
import unittest
from selenium import webdriver
from POM import LoginPage
from BasePage import BasePageObject
class TestLogin(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.driver.get("http://example.com/login")
cls.driver.maximize_window()
cls.base_page = BasePageObject(cls.driver)
def test_login_valid_credentials(self):
login_page = LoginPage(self.driver)
login_page.username.input_text("username")
login_page.password.input_text("password")
login_page.submit_button.click()
self.base_page.wait_for_element_to_be_present(login_page.welcome_message_locator)
assert "Welcome!" in self.driver.page_source
def tearDown(self):
self.driver.delete_all_cookies()
@classmethod
def tearDownClass(cls):
cls.driver.quit()
在这个测试用例中,我们使用了POM模型和Selenium自动化框架封装来实现自动化测试。首先,我们定义了LoginPage类,并通过继承PageElement来封装元素操作。然后,在测试用例中,我们可以直接调用LoginPage类中的元素和方法来进行操作。
总体来说,使用POM+Selenium自动化框架封装可以帮助我们更快速、高效地编写自动化测试用例,提高测试效率,减少测试成本。