作者:社区贡献者Shaumik Daityari和经理Pradeep Krishnakumar-2021年2月21日
在敏捷环境中,开发人员强调快速推动变更。对于需要修改前端的每项更改,他们都需要运行适当的 跨浏览器测试。尽管一个小项目可能选择 手动测试,但是越来越多的浏览器要求进行 自动测试。在这篇文章中,我们提供了通过Selenium和Python进行Web自动化测试的分步教程。
Selenium 允许您定义测试并在预定的浏览器上自动检测这些测试的结果。一套Selenium功能使您可以创建与网页的逐步交互,并评估浏览器对各种更改的响应。然后,您可以确定浏览器的响应是否符合您的期望。
这篇文章假定您没有硒的先验知识。但是,期望掌握诸如DOM之类的前端概念的基础知识以及对Python的熟悉。
使用Python运行Selenium测试的前提条件
在Python环境中安装Selenium的最简单方法是通过安装程序pip。
pip install selenium
虽然安装Selenium使您可以使用该功能,但您需要其他驱动程序才能与选定的Web浏览器进行交互。这些驱动程序的下载链接位于此处: Chrome, Edge, Firefox和 Safari。在本教程的其余部分中,我们将使用Chromedriver。单击您选择的浏览器的链接,然后下载兼容版本的驱动程序。
人们还读到: 如何使用ChromeDriver在Chrome上运行Selenium测试
如果您仅打算在本地测试Selenium,则下载软件包和驱动程序就足够了。但是,如果要在远程服务器上设置Selenium,则还需要安装Selenium Server。 Selenium Server 是用Java编写的,您需要具有JRE 1.6或更高版本才能将其安装在服务器上。可在Selenium的 下载页面上找到。
如何使用Selenium和Python运行自动化测试?
完成先决条件部分后,即可开始使用Python编程语言在Selenium中开始您的第一个测试!
1. 首先从Selenium导入webdriver和Keys类。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
webdriver类将把您连接到浏览器的实例,我们将在后面很快进行介绍。Keys类可让您模拟键盘按键的笔触,包括“ Shift”和“ Return”之类的特殊键。
2. 接下来,使用通过相应浏览器的网站下载的驱动程序的路径创建一个Chrome实例。在此示例中,我们假定驱动程序与您将执行的Python脚本位于同一目录中。
driver = webdriver.Chrome('./chromedriver')
如果您要在本地计算机上进行测试,则会在本地打开一个Chrome实例。使用此命令可以对它执行测试,直到使用 .close() 方法结束与浏览器的连接为止。
如果您想尝试使用我们的BrowserStack Automate进行本地测试,请查看此 文档。
3. 接下来,使用 驱动程序的 .get()方法加载网站。您还可以加载本地开发站点,因为此过程等效于在本地计算机上打开Chrome窗口,输入URL并按Enter。在 获得() 方法不仅开始加载一个网站,但也等待它移动到下一个步骤之前完全呈现。
driver.get("https://www.python.org")
4. 页面成功加载后,您可以使用.title属性访问网页的文本标题。如果要检查标题是否包含特定的子字符串,则可以使用assert或if语句。为简单起见,让我们打印页面标题。
print(driver.title)
输出为以下文本–
Welcome to Python.org
如果您是在Python解释器上运行测试,则会注意到Chrome浏览器窗口仍处于活动状态。另外,Chrome上的一则消息指出,目前自动化软件正在对其进行控制。
5. 接下来,让我们在搜索栏中提交查询。首先,从HTML DOM中选择元素,然后在其中输入一个值,然后通过模拟Return键来提交表单。您可以使用其CSS类,ID,其名称属性甚至标签名称来选择该元素。如果检查查询搜索栏的来源,则会注意到此DOM元素的名称属性是“ q”。因此,可以 按如下方式使用 .find_element_by_name()方法来选择元素。
search_bar = driver.find_element_by_name("q")
6. 一旦DOM元素被选择时,首先需要使用清除其内容 .clear() 方法,然后使用一个字符串作为它的值 .send_keys() 方法,最后,模拟使用回车键的按压 的按键。返回。
search_bar.clear()
search_bar.send_keys("getting started with python")
search_bar.send_keys(Keys.RETURN)
还请阅读:是否 想了解Selenium中SendKeys的其他用例? 看看吧。
您会在窗口中注意到,这些操作会触发URL的更改以及窗口中的搜索结果。要确认窗口的当前URL,可以使用以下命令。
print(driver.current_url)
显示以下字符串–
'https://www.python.org/search/?q=getting+started+with+python&submit='
要关闭当前会话,请使用 .close() 方法。它还会断开与浏览器的链接。
driver.close()
在此示例中,我们研究了使用Selenium和Python运行我们的第一个测试所涉及的步骤。请注意,我们在测试的所有阶段都将窗口保持打开状态,以确保您在运行每个命令时都知道后台发生了什么。
在全自动流程中,您将依次运行多个测试,因此,可能无法查看每个步骤的进行情况。
总结一下讨论,这是您在Python上的 第一个Selenium测试。您可以将其保存在文件 selenium_test.py中, 然后运行python selenium_test.py 来运行测试。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome('./chromedriver')
driver.get("https://www.python.org")
print(driver.title)
search_bar = driver.find_element_by_name("q")
search_bar.clear()
search_bar.send_keys("getting started with python")
search_bar.send_keys(Keys.RETURN)
print(driver.current_url)
driver.close()
浏览HTML DOM元素
现在,您已经成功使用Python在Selenium中运行了您的第一个测试,让我们看看选择DOM元素并与之交互的各种选项。在示例中,我们选择了搜索栏并查询了一个字符串。让我们进一步探讨选择。这是搜索栏的HTML。
<input id="id-search-field" name="q" type="search" role="textbox" class="search-field" placeholder="Search" value="" tabindex="1">
在示例中,我们使用了 .find_element_by_name() 方法,该方法在输入HTML标记内搜索属性名称。我们也可以使用其他方法搜索该术语。
-
CSS编号: .find_element_by_id(“ id-search-field”)
-
DOM路径: .find_element_by_xpath(“ // input [@ id ='id-search-field']”)
-
CSS类: .find_element_by_class_name(“搜索字段”)
虽然CSS ID在设计上对于每个元素都是唯一的,但是在搜索类名时,您可能会发现多个结果。此外,当您搜索元素的DOM路径时,可以确定要搜索的内容。
您知道吗: findElement 和 findElements之间的 区别? 找出来。
浏览Windows和框架
您的Web应用程序可能需要您使用多个窗口和框架。在新窗口上工作的常见用例是社交登录和文件上传。 驱动程序的 .switch_to_window()方法将帮助您更改活动窗口并在新窗口中执行不同的操作。将焦点切换到新窗口的代码是:
driver.switch_to_window('window_name')
如果该值未存储在target属性中,则可以使用窗口句柄,它唯一地标识驱动程序中所有打开的窗口。要查看所有窗口句柄的列表,请运行以下命令:
print(driver.window_handles)
同样,您可以通过.switch_to_frame() 方法将焦点切换到窗口中的框架 。要在完成相关操作后切换回主窗口,请运行以下命令。
driver.switch_to_default_content()
请注意,本节中的所有操作都会更改驱动程序的状态,并且不返回任何内容。因此,我们不将值存储在变量中,而是调用方法。
测试期间使用空闲时间
尽管我们研究了静态Web应用程序中的各种测试,但单页应用程序可能需要您等待特定的时间,直到执行操作为止。
Selenium中有两种类型的等待: 隐**式 等待 和 显式等待。显式等待使您的驱动程序等待特定的操作完成(例如使用AJAX加载内容)。隐式等待使驱动程序等待特定的时间。
对于明确的等待,您需要使用try-finally块,因为它可能使您的测试陷入最坏的情况。本质上,您指示驱动程序在放开之前等待特定的元素指定的时间。
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
try:
element = WebDriverWait(driver, 5).until(
EC.presence_of_element_located((By.ID, "id-of-new-element"))
)
finally:
driver.quit()
首先,使用 WebDriverWait() 函数告诉驱动程序等待五秒钟。然后,测试使用的加载一个新的元素 .presence_of_element_located() 的方法 expected_conditions 类,您可以通过查询 By.ID。想更多地了解 Selenium中的ExpectedConditions?
在隐式等待中,您需要使用 驱动程序的 .implicitly_wait()方法并提供驱动程序等待的秒数。
driver.implicitly_wait(5)
element = driver.find_element_by_id("id-of-new-element")
如何将Selenium与Python单元测试集成
让我们尝试了解如何将Selenium测试集成到Python单元测试中。为此,我们将在Python中使用单元测试模块。
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
class ChromeSearch(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome('./chromedriver')
def test_search_in_python_org(self):
driver = self.driver
driver.get("https://www.python.org")
self.assertIn("Python", driver.title)
elem = driver.find_element_by_name("q")
elem.send_keys("getting started with python")
elem.send_keys(Keys.RETURN)
assert "https://www.python.org/search/?q=getting+started+with+python&submit=" == driver.current_url
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()
在此示例中,通过.Chrome() 方法初始化单元测试类时,需要设置驱动程序对象 。在我们演示的单个测试中,将相同的文本放在搜索栏上,并将URL的最终更改与之前看到的URL进行比较。您可以另外为不同的浏览器编写不同的测试,并重复使用相同的功能。
如何在BrowserStack上使用Python运行Selenium测试
要通过BrowserStack在实际设备上运行Selenium,您需要先在BrowserStack上 注册。 根据免费计划,您将获得100分钟的免费测试,之后您需要订阅每月计划。
登录时,选择“ BrowserStack Automate”,然后设置要在其上运行测试的设备-浏览器组合。然后,将显示示例代码以复制并从终端运行以运行测试。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
desired_cap = {
'browserName': 'android',
'device': 'Samsung Galaxy Note 9',
'realMobile': 'true',
'os_version': '8.1',
'name': 'Bstack-[Python] Sample Test'
}
driver = webdriver.Remote(
command_executor='https://<<user>>:<<user.keys>>@hub.browserstack.com:80/wd/hub',
desired_capabilities=desired_cap)
driver.get("https://www.google.com")
if not "Google" in driver.title:
raise Exception("Unable to load google page!")
elem = driver.find_element_by_name("q")
elem.send_keys("BrowserStack")
elem.submit()
print (driver.title)
driver.quit()
让我们花点时间看一下与本文到目前为止所讨论内容的不同之处。
-
首先,您会注意到测试是在远程服务器上而不是在本地计算机上进行的。因此,您正在使用 .Remote() 方法调用具有所需设置的特定URL。Selenium Server安装在BrowserStack云上,它负责相关浏览器和设备的初始化,以供您测试。启动驱动程序后,您将熟悉其余的命令。
您知道吗:*Selenium Standalone Server* 和 Selenium Server 之间的区别 ? 找出来。
如预期的那样,以下是代码的输出。BrowserStack允许您也从仪表板实时查看正在设备上执行的测试的视频。
BrowserStack - Google Search
Selenium Python测试的局限性
尽管Selenium可以帮助您自动化测试并节省宝贵的时间,但它也有其局限性。即使拥有如此强大的测试套件,由于前端技术的不断变化的性质,您仍常常会发现自己处于尴尬的境地。
这是 使用Selenium自动化测试过程时面临的五个主要挑战。
最后的想法
在本文中,我们介绍了使用Python编程语言通过Selenium自动执行跨浏览器测试过程的各种技术。虽然我们讨论了浏览器支持,DOM导航,等待和单元测试的细微差别。最后,我们介绍了如何在BrowserStack上执行远程测试。
即使掌握了有关Selenium框架如何工作的全部知识 ,您的测试框架也仅与您设计的测试一样强大。使测试过程自动化可以在测试过程中节省大量时间,因此您应确保在设计测试时花费大量时间以捕获所有可能的情况。最好在测试阶段发现错误,而不是导致客户投诉。