在自动化前端测试时,选择理想的编程语言变得极为重要。Python就是这样一种语言,由于易于使用和广泛的社区支持,它名列前茅。
此外,Python自动化测试让您可以利用像Selenium、pytest和Robot等流行库和框架提供的功能。使用Selenium与Python结合,有助于充分发挥Selenium强大的浏览器自动化能力以及Python的简洁性和可扩展性。总体而言,Python自动化测试在全球范围内被QA广泛使用,尤其是与Selenium WebDriver一起使用。
在这篇博客中,我们将深入探讨Python在前端方面的细微差别。这篇博客的学习将对利用Python的能力来自动化简单和复杂的前端场景非常有帮助。
什么是Python自动化测试?
顾名思义,Python自动化测试是指使用Python脚本来自动化测试的过程。它是自动化手动和重复任务最受欢迎的编程语言之一。
Python自动化测试的一个简单示例涉及利用pytest框架与Selenium自动化前端测试电子商务平台。您可以验证电子商务网站的注册功能,并使用同一会话浏览网站并将所需商品添加到购物车中。通过此测试结束时,您将验证了电子商务网站的注册、登录和购物车功能。
最后,您还可以利用Python自动化系统管理、自动化电子邮件和数据处理任务。由于Python是自动化测试的先决条件,请参考下面的视频,深入了解Python的安装。
为什么选择Python进行自动化测试?
现在我们知道测试人员为什么偏爱Selenium与Python,让我们看一下选择Python进行自动化测试的一些重要原因:
1. 广泛的库和框架
PyUnit(或unittest)是Python执行单元测试的默认测试框架。虽然PyUnit可以直接使用,但Python还支持其他流行的框架,如pytest、Behave、Robot、Lettuce和Nose2。
所有这些框架都可以与Selenium和Playwright框架充分配合,用于自动化Web浏览器测试。
2. 超级简单的并行测试执行
在Selenium和Python中进行并行测试可以广泛用于执行跨不同浏览器和平台组合的Web浏览器自动化测试。虽然所有受Selenium支持的语言都支持并行测试执行,但在Python中使用起来非常简单。
3. 多范式编程语言
Python是一种多范式编程语言。因此,它对面向对象编程和结构化编程提供了全面支持。Python中的大多数特性支持函数式编程和面向切面编程。Python与Selenium结合,亦可用于对网站和Web应用程序进行功能测试。
4. 动态类型
Python语言使用动态类型和晚绑定(或动态名称解析),在执行期间绑定方法和变量名称。这一特性对于Python测试自动化非常方便。
Python还提供了如Pyre(Python 3的高性能类型检查器)和Mypy等选项,这些都是流行的静态类型检查器。通过这些检查器,Python让你可以结合动态类型和静态类型的优势。
5. 网页抓取
使用Python进行网页抓取是从网站提取有意义和有用的信息/数据的过程。它主要用于学术研究、竞争对手分析、内容聚合等。
Python提供了许多库和框架,如BeautifulSoup(bs4)、Selenium、Puppeteer和Pyppeteer,这些都简化了从网站抓取内容的任务。
6. 强大且无忧的报告
测试自动化中的报告提供了对测试执行细微差别的更大可见性(例如,测试通过/失败的百分比、测试环境、截图等)。强大的报告以简明易懂的形式提供正确的信息,可以发送给团队中的必要利益相关者,以便他们了解测试进展情况。
如何进行 Python 自动化测试?
现在我们已经了解了 Python 自动化测试的重要性,让我们动手进行一些测试。我们的讨论将主要围绕使用 Python 进行前端测试的自动化测试展开。
在开始测试之前,让我们设置虚拟环境(venv
),这有助于更好地管理环境和依赖关系。venv
在提供与基础环境中已安装的包隔离方面起着重要作用。
在终端运行命令 virtualenv venv
和 source venv
/bin
/activate
以创建虚拟环境。所有项目执行所需的依赖关系(或 Python 包),如 pytest
, selenium
等,均可在 requirements.txt 文件中找到。
pytest-selenium
pytest-xdist
selenium>=4.6.0
urllib3==1.26.12
requests
py
依赖关系
可以通过在终端触发 pip install -r requirements.txt
来安装。Selenium v4.6.0(或更高版本)作为安装程序的一部分进行安装。
为了演示,我们将使用pytest和PyUnit(或unittest)框架执行简单的Selenium Python测试。如果您熟悉这两个框架,建议您在Python中使用fixture,并在Selenium Python中使用页面对象模型以提高测试的维护性。Selenium包本身并不提供测试工具或框架。因此,我们将使用Selenium与pytest和PyUnit一起自动化与网页上元素的交互。
测试场景
- 导航到LambdaTest Selenium Playground。
- 在页面上找到输入表单提交链接。
- 在页面上输入所需的信息。
- 提交详细信息,并断言信息是否未成功提交。
实现(pytest框架)
以下是上述测试场景的测试脚本:
import os
import pytest
from os import environ
import time
from selenium.webdriver import ChromeOptions
from selenium.webdriver.support.ui import WebDriverWait
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
exec_platform = os.getenv('EXEC_PLATFORM')
time_sleep = 2
########################## Locators #########################
xSubmitForm = "//a[.='Input Form Submit']"
xInpName = "//input[@id='name']"
cInpName = "#name"
xInpEmail = "//form[@id='seleniumform']//input[@name='email']"
xInpPassword = "//input[@name='password']"
cssCompany = "#company"
cWebName = "#websitename"
xInpCountry = "//select[@name='country']"
xInpCity = "//input[@id='inputCity']"
cssAddress1 = "[placeholder='Address 1']"
cssAddress2 = "[placeholder='Address 2']"
cssInpState = "#inputState"
cssInpZip = "#inputZip"
cssInpButton = ".bg-lambda-900"
nameSearchBox = "search"
class TestFormInput:
def setup_method(self):
if exec_platform == 'cloud':
username = environ.get('LT_USERNAME', None)
access_key = environ.get('LT_ACCESS_KEY', None)
ch_options = webdriver.ChromeOptions()
lt_options = {}
lt_options["build"] = "Build: Getting Started with Selenium PyTest"
lt_options["project"] = "Project: Getting Started with Selenium PyTest"
lt_options["name"] = "Test: Getting Started with Selenium PyTest"
lt_options["browserName"] = "Chrome"
lt_options["browserVersion"] = "latest"
lt_options["platformName"] = "macOS Sonoma"
lt_options["geoLocation"] = "US"
lt_options["console"] = "error"
lt_options["w3c"] = True
lt_options["headless"] = False
ch_options.set_capability('LT:Options', lt_options)
gridURL = "https://{}:{}@hub.lambdatest.com/wd/hub".format(username, access_key)
self.driver = webdriver.Remote(
command_executor = gridURL,
options = ch_options
)
elif exec_platform == 'local':
ch_options = ChromeOptions()
self.driver = webdriver.Chrome(options=ch_options)
def test_enter_form_details(self):
resultant_str = "Thanks for contacting us, we will get back to you shortly."
driver = self.driver
driver.get("https://www.lambdatest.com/selenium-playground/")
# Commented once the tests are executed in non-headless mode
driver.maximize_window()
wait = WebDriverWait(driver, 5)
try:
element = driver.find_element(By.XPATH, xSubmitForm)
element.click()
elem_name = driver.find_element(By.XPATH, xInpName)
elem_name.send_keys("Testing")
time.sleep(time_sleep)
elem_email = driver.find_element(By.XPATH, xInpEmail)
elem_email.send_keys("[email protected]")
time.sleep(time_sleep)
elem_pass = driver.find_element(By.XPATH, xInpPassword)
elem_pass.send_keys("password")
time.sleep(time_sleep)
elem_comp = driver.find_element(By.CSS_SELECTOR, cssCompany)
elem_comp.send_keys("LambdaTest")
elem = driver.find_element(By.CSS_SELECTOR, cWebName)
elem.send_keys("https://wwww.lambdatest.com")
country_dropdown = Select(driver.find_element(By.XPATH, xInpCountry))
country_dropdown.select_by_visible_text("United States")
time.sleep(time_sleep)
elem = driver.find_element(By.XPATH, xInpCity)
elem.send_keys("San Jose")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssAddress1)
elem.send_keys("Googleplex, 1600 Amphitheatre Pkwy")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssAddress2)
elem.send_keys("Mountain View, CA 94043")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssInpState)
elem.send_keys("California")
time.sleep(time_sleep)
elem = driver.find_element(By.CSS_SELECTOR, cssInpZip)
elem.send_keys("94088")
time.sleep(time_sleep)
# Click on the Submit button
submit_button = driver.find_element(By.CSS_SELECTOR, cssInpButton)
submit_button.click()
time.sleep(2)
try:
element = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".success-msg"))
)
assert resultant_str in element.text, f"'{resultant_str}' not found in the specified element."
except Exception as e:
if exec_platform == 'cloud':
driver.execute_script("lambda-status=failed")
pytest.fail(f"Text '{resultant_str}' not found: {str(e)}")
time.sleep(2)
except Exception as e:
# Catch other exceptions
print(f"Failed: Input Form Demo, generic exception - {e}")
if exec_platform == 'cloud':
driver.execute_script("lambda-status=failed")
if exec_platform == 'cloud':
driver.execute_script("lambda-status=passed")
print(f"PyTest Demo: Test Passed")
def teardown_method(self):
if (self.driver != None):
# self.driver.close()
self.driver.quit()
if __name__ == "__main__":
pytest.main()
代码讲解
要开始,我们首先导入实现测试所需的必要模块。由于我们使用pytest,因此也将pytest
模块导入代码中。
从selenium.webdriver.support.ui模块导入WebDriverWait
类,以便我们可以在Web元素动态定位的场景中使用显式等待。expected_conditions
模块提供了一组在Selenium中可以与显式等待一起使用的预定义期望条件。
在执行任何操作之前,需要定位元素,首先定义所需元素的元素定位器。ID、名称、XPath、链接文本、部分链接文本等是一些广泛使用的网络定位器,可以帮助您在文档对象模型(DOM)中查找元素。
您可以使用浏览器本身提供的检查工具,或者像POM Builder这样的插件(或附加组件),它可以轻松找到WebElement的XPath/CSS选择器。
一旦确定了网络定位器,就可以通过将定位器与find_element()
或 find_elements()
方法结合使用来定位相应的WebElement(s)。find_element()
方法返回单个WebElement,而find_elements()
返回与定位器标准匹配的WebElement列表。
如前所述,setup_method()
是pytest的一个夹具,是初始化的一部分。该方法在执行所述测试类下的每个测试函数之前被调用。
正在实施的测试可以在本地安装的Selenium上运行,也可以在由云测试提供的在线Selenium网格上运行。LambdaTest是一个AI驱动的测试执行平台,可让您在不同浏览器和操作系统上扩展运行Python自动化测试。它带来了许多好处,主要包括减少维护、降低成本和加速测试执行。
就实现而言,唯一的变化与Selenium WebDriver有关,当在云网格上运行测试时,Selenium中的Remote WebDriver会被实例化。自动化能力生成器有助于生成测试组合的能力,这些能力旨在用于测试中。
在Selenium 4中,浏览器选项取代了期望的能力。您可以查看Selenium 3与Selenium 4差异博客,了解更多关于Selenium 4中什么已被弃用的信息。
环境变量LT_USERNAME
和LT_ACCESS_KEY
可以从您的LambdaTest帐户设置>密码与安全中获取。当与LambdaTest网格URL一起传递时,可以帮助在云网格上执行测试。在test_enter_form_details()
方法中,我们首先通过调用driver.get()
方法导航到测试URL。
接下来,实例化的浏览器窗口会被最大化,因为这被认为是Selenium的最佳实践之一。
接着,使用Selenium中的find_element()
方法结合XPath定位器定位输入表单提交元素。一旦定位到,就会调用Selenium中的按钮点击来模拟对早前步骤中定位的按钮元素的点击操作。
由于所有的测试步骤都涉及定位元素和执行操作,我们只关注几种方法。通过CSS选择器在Selenium中定位公司元素的方法如下所示。在Selenium WebDriver中,send_keys()
有助于在定位的元素中发送文本输入。
下拉菜单在网站上被广泛使用,因此,使用Selenium自动化与下拉菜单的交互对于你的测试用例来说绝对是必须的。Select
类位于selenium.webdriver.support.ui模块中,提供了处理下拉菜单的方法。
在这里,创建了一个Select
类的对象(即country_dropdown
),其输入设置为通过XPath定位的下拉菜单WebElement。select_by_visible_text()
方法帮助选择与给定字符串(即美国)匹配的可见文本项。
在表单中的所有信息输入完成并点击提交按钮后,我们等待成功消息字符串(默认:隐藏)在页面上可见。进行显式等待,使用ExpectedCondition(即定位元素的存在),直到成功消息不再出现在页面上。
如果结果字符串没有出现在页面上,则会引发断言。在云端执行时,lambda-status
变量根据执行状态标记为通过/失败。
teardown_method()
夹具包含在类中执行测试后清理资源或状态的实现。if __name__ == "__main__":
结构确保代码执行仅在脚本直接运行时进行。pytest.main()
调用pytest框架,进一步发现并执行脚本中所有启用的(即未标记为跳过)测试。
测试执行(pytest框架)
将EXEC_PLATFORM
设置为cloud后,在终端上调用以下命令在LambdaTest云网格上运行pytest测试:
pytest --verbose --capture=no tests/pytest/pytest_selenium_demo.py
以下是LambdaTest Web自动化仪表板截图,显示测试执行成功:
实施(PyUnit框架)
上述测试场景的测试脚本使用PyUnit框架位于tests/pyunit/pyunit_selenium_demo.py。
当从pytest迁移到PyUnit(或unittest)框架时,测试的核心逻辑保持不变。代码中导入的是unittest
模块,而不是pytest
模块。测试用例类继承自unittest.TestCase
,通知unittest模块这是一个测试用例。
pytest fixtures setup_method()
/teardown()
类似于PyUnit框架的setUp()
/tearDown()
方法。 setUp()
和tearDown()
方法包含初始化和去初始化的实现,分别负责初始化和去初始化。
下面显示了执行测试套件的样板代码:
if __name__ == "__main__":
unittest.main()
测试执行(PyUnit框架)
将EXEC_PLATFORM
设置为cloud后,在终端上调用以下命令以在云网格上运行PyUnit测试:
python tests/pyunit/pyunit_selenium_demo.py
下面是LambdaTest Web自动化仪表板的截图,显示测试执行成功:
如果您想在本地安装的Selenium上运行上述测试,只需将EXEC_PLATFORM
设置为local,然后您就可以进行本地执行了。
顶级Python测试框架
由于Python支持多种测试自动化框架,选择适合您项目的正确框架对于测试非常关键。选择实际上为高效测试奠定了基础。除了框架的能力之外,您还需要查看对该框架的内部专业知识。以下是一些最佳Python测试框架:
PyUnit(unittest)
它是Python中提供的默认框架。顾名思义,它主要用于单元测试。PyUnit受到Java的JUnit框架的启发,具有类似的结构和功能。
unittest框架还支持测试自动化共享测试的设置和关闭代码,测试独立于报告框架等。它还以面向对象的方式支持测试套件和测试用例。它还有一个测试运行器,负责编排测试的执行。
pytest
它是Python中最流行的测试自动化框架之一。它使用更简洁、用户友好的语法来实现测试。pytest可以用于实现单元测试以及用于测试网站和Web应用程序的复杂功能测试。
使用pytest编写的测试更加紧凑,因为该框架不需要样板代码。pytest具有内置功能,可帮助自动发现测试模块和函数。
Robot
它是一个关键驱动的开源Python框架,主要用于机器人流程自动化(RPA)和测试自动化。类似于pytest框架,Robot也是可扩展的。使用人类可读的语法/关键字可以减少学习Robot的学习曲线。
使用Robot编写的测试以`.robot`扩展名保存。如果您计划使用Robot进行前端测试,可以使用SeleniumLibrary,这是Robot Framework的Web测试库。该库支持大量关键字(点击按钮,点击图像,打开浏览器,拖放等)。
Nose2
它是Nose的继承者,是一个Python测试框架,扩展了PyUnit(或unittest)框架的功能。如果您之前有unittest的工作经验,那么使用Nose2相对较容易入门。
Nose2相比PyUnit的主要优势在于提供了大量内置的Nose插件,使测试更加简单快速。Nose2中的插件有助于测试参数化、更好地组织测试、支持fixtures、测试发现等等。
Behave
它是一个用于行为驱动开发(BDD)的Python框架。测试基于Gherkin语法,该语法基于Given-When-Then格式。
由于测试实现在场景和特性文件中,即使非技术人员也可以参与QA流程。SpecFlow(C#)和Cucumber(Java、JS、Ruby)是其他一些流行的BDD框架。
结论
到目前为止,Python显然是最适合测试自动化的脚本语言。使用Python进行自动化测试相对容易入门。它的各种测试框架可用于单元测试、跨浏览器测试等。请在下方告诉我们您在Selenium测试中首选的编程语言,以及您如何评价它与Python之间的比较,Python作为自动化测试的无可争议之王。祝您测试愉快!
Source:
https://dzone.com/articles/python-automation-testing-with-examples