Selenium安装
Selenium简介
Web应用程序的验收测试常常涉及一些手工任务。手工执行测试容易出现人为错误,也比较耗时,所以将这些任务用自动化实现。Selenium可以以自动化的方式完成Web应用程序的验收测试。
Selenium支持对浏览器的自动化测试操作,它提供一套测试函数,用于支持Web自动化测试。Selenium主要由三个工具组成:WebDriver、IDE、Grid。
Selenium架构
在客户端(client)完成Selenium脚本编写,将脚本传送给Selenium服务器,Selenium服务器使用浏览器驱动(driver)与浏览器(brower)进行交互。
Selenium核心组件
- WebDriver使用浏览器提供的API来控制浏览器,就像用户在操作浏览器一样,且不具有侵入性。
- IDE是Chrome和FireFox的扩展插件,可以录制用户在浏览器中的操作。
- Grid用于Selenium的分布式,用户可以在多个浏览器和操作系统上运行测试用例。
Selenium安装准备
第一种方式
pip install selenium
第二种方式
Selenium是Python的第三方库,用PyCharm安装Selenium的方式如下:
打开PyCharm,在PyCharm菜单栏上依次选择File -> Settings项,进入配置界面。找到Python Interpreter,然后点击+号,进入第三方库搜索界面
搜索selenium,然后点击Install Package即可。Selenium支持多种浏览器,但需要下载对应的浏览器版本的驱动,并将驱动位置设置到环境变量中。
使用Python实现自动化创建一个Chrome进程
# 导入Selenium
from selenium import webdriver
# 创建一个ChromeDriver实例,Chrome()会从环境变量中寻找浏览器驱动
dirver = webdriver.Chrome()
Selenium IDE用例录制
Selenium IDE简介
Selenium IDE是一个用于Web测试的集成开发环境,是Chrome和FireFox的插件,可以记录和回放与浏览器的交互过程。
虽然Selenium IDE可以帮我们实现生成代码、录制回放、元素定位等功能,但是它的缺点也很明显:
- 录制回放方式的稳定性和可靠性有限
- 只支持FireFox、Chrome浏览器
- 对于复杂的页面逻辑处理能力有限
Selenium IDE安装准备
Chrome插件:
https://chromewebstore.google.com/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd
FireFox插件:
Selenium IDE – Get this Extension for 🦊 Firefox (en-US)
安装完成后可以通过浏览器的菜单栏中的图标启动Selenium
实操
这里录制的操作是进入百度搜索页面搜索archer,然后点击进入archer的百度百科界面。
- 用Selenium IDE创建一个新项目,Demo00
- 然后在Playback base URL栏输入要录制脚本的网站URL
- 输入URL之后,点击右上角REC按钮开始录制,此时会以输入的URL打开一个浏览器窗口,在这个窗口手动执行想要录制的相关操作后,再次点击REC按钮结束录制。结束路之后给这个录制命名
- 想要导出对应的Python代码,右击刚刚录制完成的测试用例,选择Export。
- 然后选择Python pytest选项,选择EXPORT即可完成导出。
- 导出的代码
# Generated by Selenium IDE
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
class TestBaidusearchtest():
def setup_method(self, method):
self.driver = webdriver.Chrome()
self.vars = {}
def teardown_method(self, method):
self.driver.quit()
def wait_for_window(self, timeout = 2):
time.sleep(round(timeout / 1000))
wh_now = self.driver.window_handles
wh_then = self.vars["window_handles"]
if len(wh_now) > len(wh_then):
return set(wh_now).difference(set(wh_then)).pop()
def test_baidusearchtest(self):
# Test name: baidu_search_test
# Step # | name | target | value
# 1 | open | https://www.baidu.com/ |
self.driver.get("https://www.baidu.com/")
# 2 | setWindowSize | 1294x1400 |
self.driver.set_window_size(1294, 1400)
# 3 | click | id=kw |
self.driver.find_element(By.ID, "kw").click()
# 4 | type | id=kw | archer
self.driver.find_element(By.ID, "kw").send_keys("archer")
# 5 | sendKeys | id=kw | ${KEY_ENTER}
self.driver.find_element(By.ID, "kw").send_keys(Keys.ENTER)
# 6 | click | linkText=Archer(Fate系列作品中的用语) - 百度百科 |
self.vars["window_handles"] = self.driver.window_handles
# 7 | selectWindow | handle=${win3682} |
self.driver.find_element(By.LINK_TEXT, "Archer(Fate系列作品中的用语) - 百度百科").click()
self.vars["win3682"] = self.wait_for_window(2000)
self.driver.switch_to.window(self.vars["win3682"])
- 回放与保存
- 控件定位,点击Command栏的click,然后点击下方Target后面的按钮,会跳转到浏览器页面
- 移动鼠标可以高亮网页上的元素,如果点击对应高亮控件,此时Selenium IDE窗口上的Target值会编程相应的定位表达式。
Selenium测试用例编写
Selenium测试用例简介
编写Selenium测试用例的目的是模拟用户在浏览器上的一些列操作,通过测试脚本来完成对被测对象的自动化测试。编写Selenium测试用例的优势:
- Selenium开源免费
- Selenium支持多种浏览器,如IE、FireFox、Chrome、Safari
- Selenium支持多种平台,如Windows、Linux
- Selenium支持多种语言,如Python、Java、C#
- Selenium对Web支持良好
- Selenium使用简单、灵活
- Selenium支持多种分布式测试用例执行
引入依赖
Selenium引入依赖是为了调用webdriver中的方法来与浏览器进行交互,以实现测试操作
from selenium import webdriver
测试用例流程
测试用例是测试人员为了实施测试而向被测系统提供的一个特定的集合,这个集合包含测试环境、操作步骤、测试数据、预期结果等。一个测试用例被实施后产生的结果只有一个:成功或者失败。测试用例流程的三大核心要素为:标题、步骤、预期结果。
- 标题:是对测试用例的描述,标题应该清楚地表达测试用例的内容
- 步骤:对测试执行过程进行描述
- 预期结果:提供测试执行的预期结果,预期结果一般是根据需求得出。
实战
测试步骤:
- 打开百度页面
- 在百度的首页获取"百度一下"文本内容
- 将获取到的文本与"百度"进行比较。
# 导入Selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
def test_baidu_search():
# 创建一个ChromeDriver实例,Chrome()会从环境变量中寻找浏览器驱动
driver = webdriver.Chrome()
# 测试步骤
driver.get("https://www.baidu.com")
# 查找搜索按钮并获取其属性值
search = driver.find_element(By.ID, "su").get_attribute("value")
# 断言预期结果
assert search == "百度"
# 关闭浏览器
driver.quit()
隐式等待、显示等待和强制等待
等待机制简介
系统在实际工作中引入等待机制可以保证代码运行的稳定性,保证代码运行不会受网速、计算机性能等条件约束。
等待就是当系统运行时,如果页面的渲染速度跟不上程序的运行速度,就需要人为地去限制程序执行的速度。
测试人员在做Web自动化测试时,一般要等待页面元素加载完成后,才能执行测试操作,否则会报找不到元素等错误,这样就需要在有些测试场景下加上等待机制。
最常见的3种等待机制
隐式等待
在测试用例种设置一个隐式等待事件,测试用例执行时会按事件轮询查找(默认0.5秒)元素是否出现,如果轮询查找的时间内元素没有出现系统就抛出异常。
隐式等待的作用是全局的,隐式等待可以在setup方法种设置,是作用在整个Session的声明周期的。也就是说只要设置一次隐式等待,后面就不需要再设置了。
在DOM结构中查找元素,且元素处于不能立即交互的状态时,将会触发隐式等待:
self.driver.implicitly_wait(30)
显式等待
显式等待是通过在代码种定义等待条件,触发该条件后再执行后续代码,这是根据判断条件进行等待。这里通过导入expected_conditions这个库满足显式等待所需的使用场景,但是expected_conditions库并不能满足所有场景。
# 导入Selenium
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
driver = webdriver.Chrome()
# 设置10秒的最大等待时间,等待(By.TAG_NAME, "title")这个元素被点击
WebDriverWait(driver, 10).until(
expected_conditions.element_to_be_clickable((By.TAG_NAME, "title"))
)
强制等待
强制等待是使程序中的线程休眠一定时间。强制等待一般在隐式等待和显式等待都不起作用时使用。
# 等待10秒
time.sleep(10)
Web控件定位与场景操作
在较新的Selenium中,一些旧方法已经弃用,取而代之的时find_element和find_elements方法,结合By类来定位元素。find_elements和find_element类似,区别在于find_elements返回的是一个元素列表,而不是单个元素。
旧方法新方法find_element_by_idfind_element(By.ID, "id_value")find_element_by_namefind_element(By.NAME, "name_value")find_element_by_class_namefind_element(By.CLASS_NAME, "class_name_value")find_element_by_tag_namefind_element(By.TAG_NAME, "tag_value")find_element_by_xpathfind_element(By.XPATH, "xpath_value")find_element_by_link_textfind_element(By.LINK_TEXT, "link_text_value")find_element_by_partial_link_textfind_element(By.PARTIAL_LINK_TEXT, "partial_link_text_value")find_element_by_css_selectorfind_element(By.CSS_SELECTOR, "css_selector_value")
- By.ID:ID通常唯一,定位速度最快
- By.NAME:如果ID不可用且NAME是唯一的,可以使用NAME
- By.CLASS_NAME:当CLASS_NAME是唯一且稳定时使用
- By.TAG_NAME:通常用于查找一组元素,不常用于单个元素的定位
- By.LINK_TEXT:用于定位链接文本完全匹配的标签
- By.PARTIAL_LINK_TEXT:用于定位链接文本部分匹配的标签
- By.CSS_SELECTOR:非常灵活且强大,可用于复杂的定位,但需要对CSS选择器有一定的了解
- By.XPATH:最灵活但最慢,适用于复杂的定位需求。尽量避免使用过于复杂的XPath表达式
通过id定位元素
driver.find_element(By.ID, "wd")
通过name定位元素
driver.find_element(By.NAME, "wd")
通过XPath定位元素
XPath是一种定位语言,全称XML Path Language,用来对XML中的元素进行定位,也适用于HTML。
定位百度搜索框:F12进入开发者模式,定位到搜索框,在HTML代码中找到对应的input,右键选择Copy->Copy XPath得到"//*[@id="kw"]"。XPath中//可以找到子孙节点,而/只能找到子节点
driver.find_element(By.XPATH, "//*[@id="kw"]")
常用XPath表达式:
表达式描述nodename选取此节点的所有子节点/从根节点选取//从匹配的当前节点选择文档中的节点.选取当前节点..选取当前节点的父节点@选取属性
验证XPath是否正确,可以进入开发者模式,点击Console,输入$x("XPath表达式")看匹配的元素是否正确
通过css_selector定位元素
XPath可以定位绝大多数元素,但是XPath采用从上到下的遍历模式,遍历速度并不快,而采用css_selector采用样式定位,速度优于XPath,语法也更简洁。
常用css_selector表达式:
表达式描述.introclass="intro"的所有元素#firstnameid="firstname"的所有元素a[target=_blank]具有属性target="_blank"的所有a元素p:nth-child(2)父元素的第二个p元素
同样在开发者模式Console中输入$("css_selector表达式")即可完成CSS表达式的检测。
通过link定位元素
也可以通过页面元素中的链接文本定位元素。
driver.find_elements(By.LINK_TEXT, "新闻")
可以采用部分匹配方式,匹配的关键词可以不全。
driver.find_elements(By.PARTIAL_LINK_TEXT, "新")
通过tag_name定位元素
DOM结构中,元素都有自己的tag,如input、button等。
driver.find_elements(By.TAG_NAME, "input")
通过class_name定位元素
通过元素的class属性进行定位
driver.find_elements(By.CLASS_NAME, "some_class")
Selenium常见操作
- 输入、点击、清除
- 关闭窗口和浏览器
- 获取元素属性
- 获取网页源代码、刷新页面
- 设置窗口大小
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
def selenium_demo():
# 创建一个ChromeDriver实例,Chrome会从环境变量中寻找浏览器驱动
driver = webdriver.Chrome()
# 打开百度首页
driver.get("https://www.baidu.com")
# 输入关键词到搜索狂
search_input = driver.find_element(By.ID, "kw")
search_input.send_keys("Selenium")
# 获取搜索框的属性值
search_value = search_input.get_attribute("value")
print(f"Search input value:{search_value}")
# 点击搜索按钮
search_button = driver.find_element(By.ID, "su")
search_button.click()
# 等待几秒以便搜索结果加载
time.sleep(3)
# 获取网页源代码
page_source = driver.page_source
print(f"Page source length:{len(page_source)}")
# 刷新网页
driver.refresh()
# 等待几秒页面刷写
time.sleep(3)
# 刷新页面之后需要重新获取搜索框元素
search_input = driver.find_element(By.ID, "kw")
# 清除搜索框内容
search_input.clear()
# 设置窗口大小
driver.set_window_size(1024, 768)
# 最小、最大化窗口
driver.minimize_window()
driver.maximize_window()
# 关闭当前窗口
driver.close()
# 关闭浏览器
driver.quit()
if __name__ == "__main__":
selenium_demo()
版权归原作者 竹筒饭啊 所有, 如有侵权,请联系我们删除。