Selenium安装
关于Selenium安装,请查看此文章→Selenium+ChromeDriver安装及配置
Selenium IDE使用
关于使用Selenium脚本录制,请查看此文章→Selenium IDE的使用方法
Selenium元素定位
若想操作Web界面上的元素,首先要定位到元素,selenium提供了定位元素的API,这些方法被定义在WebDriver类中,都是以find开头
-
ID定位 def test_id(self):
self.driver.find_element_by_id("kw").send_keys("功能测试")
self.driver.find_element_by_id("su").click()
-
name定位 def test_name(self):
self.driver.find_element_by_name("wd").send_keys("接口测试")
self.driver.find_element_by_name("wd").click()
-
class定位 def test_ClassName(self):
self.driver.find_element_by_class_name("s_ipt").clear()
self.driver.find_element_by_class_name("s_ipt").send_keys("性能测试")
self.driver.find_element_by_class_name("bg").click()
-
xpath定位 当没有适合的id、name、classname使用时,可选择使用xpath定位方法,具体使用方法可参考此文章 def test_xpath(self):
self.driver.find_element_by_xpath('//*[@id="kw"]').clear()
elem2 = self.driver.find_element_by_xpath('//*[@id="kw"]').send_keys("安全测试")
self.driver.find_element_by_xpath('//*[@id="su"]').click()
-
链接文本定位 def test_LinkText(self):
self.driver.find_element_by_link_text("百度首页").click()
-
部分链接文本定位 def test_PartLinkText(self):
self.driver.find_element_by_partial_link_text("术").click()
self.driver.find_elements_by_partial_link_text("度")[1].click()
-
CSS选择器定位 选择器是CSS中的重点,它的功能就是告诉浏览器具体位置,可理解为门牌号 def test_CssSelector(self):
self.driver.find_element_by_css_selector("#kw").send_keys("软件测试工程师")
self.driver.find_element_by_css_selector("#su").click()
-
Tag标签定位 Tag通常定义一类功能,所以通过tag定位某一个元素的概率很低,tag定位方法用到较少,因为它不太容易准确定位 def test_Tag(self):
ent = self.driver.find_elements_by_tag_name("input")
ent[1].send_keys("测开")
print(ent)
所有元素定位方式都有复数形式,如上文中的“部分链接文本定位”,所有的find_element_… 都有复数形式find_elements_… ,存在多个值时使用elements 可获得值的列表,可以通过下标定位具体的元素,比如:find_elements_by_id("su")[0] 与find_element_by_id("su") 的值是一样的
find_element_…() 可以使用By类代替,find_element() 可以自定义定位方式,如:find_element(By.ID)
Selenium页面对象
WebDriver常用属性
print(self.driver.name)
print(self.driver.title)
print(self.driver.current_url)
print(self.driver.window_handles)
print(self.driver.current_window_handle)
print(self.driver.page_source)
self.driver.back()
self.driver.forward()
self.driver.refresh()
self.driver.close()
self.driver.quit()
self.driver.switch_to.alert
self.driver.switch_to.frame()
self.driver.switch_to.window
self.driver.switch_to.default_content()
self.driver.switch_to.active_element
示例如下:
def test_attr(self):
print(self.driver.name)
print(self.driver.title)
b = self.driver.current_url
print(self.driver.current_window_handle)
print(self.driver.page_source)
self.driver.close()
sleep(1)
def test_method(self):
self.driver.find_element(By.LINK_TEXT,"知识").click()
self.driver.back()
self.driver.forward()
self.driver.refresh()
self.driver.find_element(By.LINK_TEXT,"热门").click()
win = self.driver.window_handles
while 1:
for w in win:
self.driver.switch_to.window(w)
sleep(5)
self.driver.quit()
WebElement常用属性
id
size
rect
text
tag_name
send_keys()
clear()
click()
get_attribute()
is_selected()
is_enabled()
is_displayed()
value_of_css_property()
示例如下:
def test_webele(self):
a = self.driver.find_element(By.CLASS_NAME,"nav-search-keyword")
print(type(a))
print(a.id)
print(a.size)
print(a.rect)
print(a.text)
print(a.tag_name)
a.send_keys("测试开发")
print(a.get_attribute("class"))
print(a.value_of_css_property("font"))
print(a.is_selected())
print(a.is_enabled())
print(a.is_displayed())
a.clear()
a.click()
可以通过按住Ctrl键并单击某个属性或方法,查看源码,了解其使用方法。比如要了解chromedriver,可以按住ctrl键并单击Chrome
Selenium 弹框处理
页面弹框有三种:
-
alert:用于提示弹框,只是提示信息 -
confirm:用于确认的弹框,常用于删除、提交的二次确认,有取消和确认按钮 -
prompt:输入内容,用于需要填写信息的弹框,有输入框、取消及确认按钮 属性:accept() 确认;dismiss()取消;text显示的提示信息;send_keys输入内容
test = self.driver.switch_to.alert
ptint(test.text)
test.accept()
test.dismiss()
Select常用属性
操作下拉列表时使用
select_by_index(2)
select_by_value("o1")
select_by_visible_text("o3")
deselect_all()
deselect_by_index(3)
deselect_by_value("o2val")
deselect_by_visible_text("With spaces")
options
all_selected_options
first_selected_options
示例如下:
def test_select(self):
ele = self.driver.find_element(By.ID,"s1Id")
sel = Select(ele)
sel.select_by_index(2)
sel.select_by_value("o1")
sel.select_by_visible_text("o3")
def test_deselect(self):
ele1 = self.driver.find_element(By.ID,"s4Id")
sel1 = Select(ele1)
for i in range(6):
sel1.select_by_index(i)
sel1.deselect_all()
sel1.deselect_by_index(3)
sel1.deselect_by_value("o2val")
sel1.deselect_by_visible_text("With spaces")
for option in sel1.options:
print(option.text)
Selenium等待事件
在进行UI自动化测试时,必然会出现网络不稳定,延迟高,网络慢等问题,或者页面使用了Ajax异步加载机制,这些情况下若不做处理,代码会由于找不到元素而报错,所以需要先等待页面加载完成,Selenium中可使用三种等待方式,固定等待、显式等待和隐式等待
固定等待(time.sleep):此方式是人为设定的线程阻塞时间,只在脚本调试时使用
在开发自动化框架过程中,最忌讳使用Python自带模块time的sleep方式进行等待,虽可自定义时间,但在网络良好时也会按照预设时间继续等待,导致整个项目自动化时间无限延长,在实际项目中不建议使用,需导入sleep包,导入路径from time import sleep
示例如下:
def test_sleep(self):
ele = self.driver.find_element_by_link_text("知识")
sleep(2)
ele.click()
sleep(3)
self.driver.quit()
隐式等待(implicitly_wait):此等待方式对全局起作用,只需在开始时设置一次
隐式等待实际上是设置了一个最长的等待时间,若在设定时间内页面加载完成,则执行下一步,否则会一直等到时间结束,因元素未找到而抛出异常,此方式不够灵活,需等待页面所有元素加载完成
示例如下:
def test_implicitly(self):
self.driver.implicitly_wait(3)
self.driver.find_element_by_class_name("nav-search-keyword").send_keys("测开")
self.driver.find_element_by_class_name("nav-search-btn").click()
self.driver.quit()
显式等待(WebDriverWait):此方式是一种动态等待方式,是比较常用的,也是相对复杂一些的的等待方式
此等待方式需导入WebDriverWait和expected_conditions包,导入路径如下:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
WebDriverWait的参数:
driver
timeout
poll_frequency
ignored_exceptions
显式等待模块只有两种方法until和until_not,调用驱动程序提供的方法作为参数,直到返回值不为False为止,参数如下:
method
message
示例如下:
def test_WebDriverWait(self):
handle = self.driver.current_window_handle
self.driver.find_element_by_link_text("热门").click()
handles = self.driver.window_handles
for newhandle in handles:
if newhandle != handle:
self.driver.switch_to.window(newhandle)
WebDriverWait(self.driver, 3).until(expected_conditions.title_is("哔哩哔哩热门"),message="页面加载错误")
self.driver.find_element_by_class_name("mask-tips-step").click()
self.driver.quit()
expected_conditions的常用属性,导入路径from selenium.webdriver.support import expected_conditions as EC
title_is
title_contains
presence_of_element_located
visibility_of_element_located
visinility_of_any_elements_located
presence_of_all_elements_located
text_to_be_present_in_element
alert_is_present
visibility_of
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable
staleness_of
element_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
示例如下:
def test_dyd(self):
self.driver.get("https://www.bilibili.com/")
WebDriverWait(self.driver,3).until(EC.title_is("哔哩哔哩 (゜-゜)つロ 干杯~-bilibili"))
self.driver.find_element(By.LINK_TEXT,"科技").click()
handle = self.driver.current_window_handle
handles = self.driver.window_handles
for newhandle in handles:
if newhandle != handle:
self.driver.switch_to.window(newhandle)
WebDriverWait(self.driver,2).until(EC.title_contains("科技区"),message="页面加载失败")
WebDriverWait(self.driver,3).until(EC.presence_of_element_located((By.LINK_TEXT, '软件应用')))
WebDriverWait(self.driver,1).until(EC.presence_of_all_elements_located((By.LINK_TEXT,"全部")))
WebDriverWait(self.driver,4).until(EC.visibility_of_element_located((By.LINK_TEXT,"数码")))
WebDriverWait(self.driver,5).until(EC.visibility_of_any_elements_located((By.LINK_TEXT,"热门")))
WebDriverWait(self.driver,2).until(EC.text_to_be_present_in_element((By.PARTIAL_LINK_TEXT,"计算"),"技术"))
try:
WebDriverWait(self.driver,3).until(EC.alert_is_present())
except:
print("指定时间内未找到弹窗")
Selenium鼠标与键盘事件
Selenium中的鼠标与键盘事件是封装在ActionChains类中的,使用方法举例ActionChains(driver).click(btn).perform() ,常用方法如下:
click()
double_click()
context_click()
click_and_hold()
drag_and_drop(source,target)
move_to_element(to_element)
move_by_offset(xoffset,yoffset)
move_to_element_with_offset(to_element,xoffset,yoffset)
key_down(value,element=None)
key_up(value,element=None)
perform()
relesae()
send_keys()
鼠标事件示例如下:
def test_mouse(self):
self.driver.get("http://www.sahitest.com/demo/clicks.htm")
cli = self.driver.find_element(By.XPATH,"//input[3]")
ActionChains(self.driver).click(cli).perform()
dblcli = self.driver.find_element(By.XPATH,"//input[2]")
ActionChains(self.driver).double_click(dblcli).perform()
ActionChains(self.driver).click_and_hold(cli).perform()
ActionChains(self.driver).release(cli).perform()
cliR = self.driver.find_element(By.XPATH,"//input[4]")
ActionChains(self.driver).context_click(cliR).perform()
def test_dragdrop(self):
self.driver.get("http://www.sahitest.com/demo/dragDropMooTools.htm")
sourse = self.driver.find_element(By.ID,"dragger")
target = self.driver.find_element(By.XPATH,'//div[@class="item"][1]')
ActionChains(self.driver).drag_and_drop(sourse,target).perform()
ActionChains(self.driver).drag_and_drop_by_offset(sourse,137,115).perform()
键盘事件需要用到Keys类,导入Keys类后,在源码中可以看到常用的虚拟按钮代码,可以通过keys直接调用,键盘事件示例如下:
def test_keyboard(self):
self.driver.get("https://www.bilibili.com/")
kb = self.driver.find_element(By.CLASS_NAME,"nav-search-keyword")
kb.send_keys("Web自动化测试")
kb.send_keys(Keys.CONTROL,"a")
kb.send_keys(Keys.CONTROL,"x")
kb.send_keys(Keys.CONTROL,"v")
kb.send_keys(Keys.CONTROL,"a")
kb.send_keys(Keys.DELETE)
ActionChains(self.driver).key_down(Keys.CONTROL,kb).send_keys("测试").key_up(Keys.CONTROL).perform()
ele = self.driver.find_element(By.LINK_TEXT,"热门")
ActionChains(self.driver).move_to_element(ele).perform()
print(self.driver.find_element(By.ID,"reportFirst1").rect)
ActionChains(self.driver).move_by_offset(139.6666717529297,263).perform()
ActionChains(self.driver).move_to_element_with_offset(ele,523,305).perform()
以下为实际项目练习部分用例
1、网站注册测试用例
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from util import util
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
class TestUserRegister(object):
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.get("http://192.166.66.25:8080/dyd/user/register")
self.driver.maximize_window()
def test_user_register_username(self):
username = ""
email = util.gen_random_str() + "@qq.com"
pwd = "123456"
confirmPwd = "123456"
captcha = "6666"
expected = "用户名不能为空"
self.driver.find_element(By.NAME, "username").send_keys(username)
self.driver.find_element(By.NAME, "email").send_keys(email)
self.driver.find_element(By.NAME, "pwd").send_keys(pwd)
self.driver.find_element(By.NAME, "confirmPwd").send_keys(confirmPwd)
self.driver.find_element(By.NAME, "captcha").send_keys(captcha)
self.driver.find_element(By.CLASS_NAME, "btn").click()
WebDriverWait(self.driver, 3).until(EC.alert_is_present())
alert = self.driver.switch_to.alert
assert alert.text == expected
alert.accept()
def test_user_register_OK(self):
username = util.gen_random_str()
email = util.gen_random_str() + "@qq.com"
pwd = "123456"
confirmPwd = "123456"
captcha = ""
expected = "注册成功,点击确定进行登录。"
self.driver.find_element(By.NAME, "username").clear()
self.driver.find_element(By.NAME, "username").send_keys(username)
self.driver.find_element(By.NAME, "email").clear()
self.driver.find_element(By.NAME, "email").send_keys(email)
self.driver.find_element(By.NAME, "pwd").clear()
self.driver.find_element(By.NAME, "pwd").send_keys(pwd)
self.driver.find_element(By.NAME, "confirmPwd").clear()
self.driver.find_element(By.NAME, "confirmPwd").send_keys(confirmPwd)
captcha = util.get_code(self.driver, "captchaimg")
self.driver.find_element(By.NAME, "captcha").clear()
self.driver.find_element(By.NAME, "captcha").send_keys(captcha)
self.driver.find_element(By.CLASS_NAME, "btn").click()
WebDriverWait(self.driver, 3).until(EC.alert_is_present())
alert = self.driver.switch_to.alert
assert alert.text == expected
alert.accept()
sleep(1)
self.driver.quit()
2、网站登录测试用例
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
class TestUserLogin(object):
def __init__(self):
self.driver = webdriver.Chrome()
self.driver.get("http://192.166.66.25:8080/dyd/user/login")
self.driver.maximize_window()
def test_user_login_nameEmpty(self):
username = ""
pwd = "123456"
expected = "账号不能为空"
self.driver.find_element(By.NAME,"pwd").send_keys(pwd)
self.driver.find_element(By.CLASS_NAME,"btn").click()
WebDriverWait(self.driver,3).until(EC.alert_is_present())
alert = self.driver.switch_to.alert
assert alert.text == expected
alert.accept()
def test_user_login_OK(self):
username = "admin"
pwd = "123456"
expected = "用户中心"
self.driver.find_element(By.NAME, "user").clear()
self.driver.find_element(By.NAME, "user").send_keys(username)
self.driver.find_element(By.NAME, "pwd").clear()
self.driver.find_element(By.NAME, "pwd").send_keys(pwd)
self.driver.find_element(By.CLASS_NAME, "btn").click()
WebDriverWait(self.driver, 3).until(EC.title_is(expected))
assert self.driver.title == expected
self.driver.quit()
下图是注册登录测试用例执行过程 3、文章分类测试用例
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
class TestCategory(object):
def __init__(self, login):
self.login = login
def test_add_CategoryEmpoty(self):
title = ""
parent = "顶级"
slug = "www.dyd.com"
content = "这是正文内容"
describe = "这是文章描述"
expected = "分类名称不能为空"
self.login.driver.find_element(By.XPATH,'//*[@id="sidebar-menu"]/li[4]/a/span[1]').click()
sleep(1)
self.login.driver.find_element(By.XPATH,'//*[@id="sidebar-menu"]/li[4]/ul/li[3]/a').click()
self.login.driver.find_element(By.NAME,"category.title").send_keys(title)
parent_catepory_elem = self.login.driver.find_element(By.NAME,"category.pid")
Select(parent_catepory_elem).select_by_visible_text(parent)
self.login.driver.find_element(By.NAME,"category.slug").send_keys(slug)
self.login.driver.find_element(By.NAME,"category.content").send_keys(content)
self.login.driver.find_element(By.NAME,"category.meta_description").send_keys(describe)
sleep(1)
self.login.driver.find_element(By.XPATH, '/html/body/div/div/section[2]/div/div[1]/div/form/div[2]/div/div/button').click()
sleep(1)
loc = (By.CLASS_NAME,"toast-message")
WebDriverWait(self.login.driver,5).until(EC.visibility_of_element_located(loc))
msg = self.login.driver.find_element(*loc).text
assert msg == expected
def test_add_OK(self):
title = "见溪"
parent = "顶级"
slug = "www.dyd.com"
content = "树深时见鹿,溪午不闻钟"
describe = "一念清净,烈焰成池"
self.login.driver.find_element(By.XPATH, '//*[@id="sidebar-menu"]/li[4]/ul/li[3]/a').click()
self.login.driver.find_element(By.NAME, "category.title").send_keys(title)
parent_catepory_elem = self.login.driver.find_element(By.NAME, "category.pid")
Select(parent_catepory_elem).select_by_visible_text(parent)
self.login.driver.find_element(By.NAME, "category.slug").send_keys(slug)
self.login.driver.find_element(By.NAME, "category.content").send_keys(content)
self.login.driver.find_element(By.NAME, "category.meta_description").send_keys(describe)
sleep(1)
self.login.driver.find_element(By.XPATH, '/html/body/div/div/section[2]/div/div[1]/div/form/div[2]/div/div/button').click()
assert 1 == 1
sleep(1)
self.login.driver.quit()
下图为分类测试用例执行结果
|