一、环境搭建
1、安装selenium
2、下载webdriver
(1)检查chrome版本
(2)下载对应版本chromedriver
网址 https://chromedriver.chromium.org/
(3)下载后解压,将解压后文件放到/usr/bin的目录下
二、简单程序模拟
from selenium import webdriver
from time import sleep
#生成一个Chromedriver
driver = webdriver.Chrome()
#访问制定的URL
driver.get('https://blog.csdn.net/')
#输入"jenkins"
driver.find_element_by_id('toolbar-search-input').send_keys('jenkins')
#点击"搜索按钮"
driver.find_element_by_id('toolbar-search-button').click()
#等待
sleep(2)
#点击第一条链接
driver.find_element_by_xpath('//*[@id="floor-blog-index_747"]/div/div[1]/div[1]/div[1]/div/a/span').click()
三、关键字驱动(selenium二次封装)
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
class TestKeyWords(object):
#初始化
def __init__(self,url,browser_type):
self.driver = self.open_browser(browser_type)
self.driver.get(url)
#调用浏览器
def open_browser(self,browser_type):
global driver
if browser_type == 'chrome':
driver = webdriver.Chrome()
return driver
elif browser_type == 'firefox':
driver = webdriver.Firefox()
return driver
else:
print('type error')
# ActionChains(self.driver).key_down(Keys.CONTROL).send_keys("t").key_up(Keys.CONTROL).perform()
#元素定位
def location(self,location_type,value):
if location_type == 'xpath':
el = self.driver.find_element_by_xpath(value)
return el
elif location_type == 'id':
el = self.driver.find_element_by_id(value)
return el
elif location_type == 'name':
el = self.driver.find_element_by_name(value)
return el
# def location1(self,*value):
# return self.driver.find_element(value)
#输入
def input_text(self,location_type,value,text):
self.location(location_type,value).send_keys(text)
#点击
def click_element(self,location_type,value):
self.location(location_type,value).click()
if __name__ == '__main__':
tk = TestKeyWords('https://blog.csdn.net/','chrome')
tk.input_text('id','toolbar-search-input','jenkins')
tk.click_element('id','toolbar-search-button')
四、数据驱动
1、数据驱动
将代码与数据进行分离,单纯由数据组成文件,再由文件来驱动关键字,最终实现整个自动化流程。
2、数据驱动+关键字驱动形式下实现的自动化测试框架
读取到数据,基于固定格式的数据内容进行拼接,拼接后的内容作为关键字所需要的参数,进行传入。从而执行对应的关键字,再将结果与预期进行对比,从而获得单条测试用例是否执行通过。
3、unitTest
通过直接导入unitTest包即可实现,主要用于管理测试用例以及实现数据驱动。
quit和close的区别
quit关闭浏览器,并且关闭当前的Chromedriver进程
close 关闭当前的标签页,不会关闭进程
3、unitTest+DDT实现数据驱动
import unittest
from time import sleep
from test_keywords_demo import TestKeyWords
from ddt import ddt,data,unpack
@ddt
class TestForKey(unittest.TestCase):
#前置条件
def setUp(self) -> None:
self.tk = TestKeyWords('https://blog.csdn.net/', 'chrome')
#后置条件
def tearDown(self) -> None:
self.tk.quit_browser()
#测试用例
@data(['id','jenkins'],['id','docker'])
@unpack
def test1(self,locator,input_text):
self.tk.input_text(locator, 'toolbar-search-input', input_text)
self.tk.click_element('id', 'toolbar-search-button')
sleep(3)
if __name__ == '__main__':
unittest.main()
五、PO(PageObject)模式
完全基于页面来实现的模型
1、PO设计原理
(1)提取selenium中公用的方法,作为基本对象
(2)页面业务流程的关联设计
(3)调用业务流程实现自动化测试
优势
(1)将不同的页面封装成不同的页面对象,分别进行管理
(2)进一步降低冗余
(3)对于代码的可读性和维护性有进一步提升
2、PO是如何实现的?
class BasePage(object):
# driver = webdriver.Chrome()
#初始化
def __init__(self,driver):
self.driver = driver
#元素定位
def locator(self,locator):
return self.driver.find_element(*locator)
#关闭浏览器
def quit_browser(self):
self.driver.quit()
#访问
def visit(self,url):
self.driver.get(url)
from selenium.webdriver.common.by import By
from basePage.base_page import BasePage
from selenium import webdriver
class SearchPage(BasePage):
#搜索框
input_id = (By.ID,'toolbar-search-input')
#按钮
click_id = (By.ID,'toolbar-search-button')
#对搜索框进行内容的输入
def input_text(self,input_text):
self.locator(self.input_id).send_keys(input_text)
#点击查询按钮,实现本次搜索
def click_element(self):
self.locator(self.click_id).click()
def check(self,url,input_text):
self.visit(url)
self.input_text(input_text)
self.click_element()
if __name__ == "__main__":
url = 'https://blog.csdn.net/'
driver = webdriver.Chrome()
sp = SearchPage(driver)
#进行调试
sp.check(url,'jenkins')
3、PO+UnitTest+DDT
import unittest
from time import sleep
from ddt import ddt,data,unpack
from selenium import webdriver
from pageObject.search_page import SearchPage
@ddt
class TestCases(unittest.TestCase):
#前置条件
def setUp(self) -> None:
driver = webdriver.Chrome()
self.sp = SearchPage(driver)
#后置条件
def tearDown(self) -> None:
self.sp.quit_browser()
@data(['https://blog.csdn.net/','jenkins'],['https://blog.csdn.net/','docker'])
@unpack
def test_1(self,url,input_text):
self.sp.check(url,input_text)
sleep(3)
if __name__ == "__main__":
unittest.main()
六、八大元素定位
1、id:基于元素属性中的id的值来进行定位,不出意外都不会重复
find_element_by_id('id')
2、name:基于元素属性中的name的值来进行定位,很可能出现重名
find_element_by_name('name')
3、link text:主要用于超链接进行定位
find_element_by_link_text('')
4、partral link text:link text的模糊查询版本,类似于数据库的like %
当模糊查询匹配到多个符合条件的元素,选取第一个
find_element_by_partral_link_text('')
5、classname:基于元素样式来进行定位,非常容易遇到重复的
find_element_by_class_name('')
6、tagname:标签名来进行定位,重复率最高。只有在定位后需要进行二次筛选的情况下使用
find_element_by_tag_name('')
7、cssselector:应用相对较多的一种行为,最初IE浏览器不支持xpath,完全基于xpath属性来实现的定位。
find_element_by_css_selector('')
8、xpath:目前应用最多的一种行为,基于页面结构来进行的定位
find_element_by_xpath('xpath')
绝对路径:从html路径,一层层往下数,找到对应的层级,从而找到元素。除非十万火急,否则不要这么写
相对路径:基于匹配制度来查找元素,依照xpath语法结构来走。
例如://*[@id=“kw”]
//:表示从根路径下开始查找
*:任意元素
[]:表示筛选条件(查找函数)
@:表示基于属性来筛选,例如@id=“kw” 表示基于id属性,值为kw的条件进行筛选。
确认xpath路径是否正确:
1⃣️在开发者工具elements页面使用ctrl+f查找,进行判断
2⃣️在console中输入$x()进行校验
如果要基于text文本来定位元素
在[]中添加text()=“文本内容”进行查找,例如://a[text()=‘登陆’]
当你定位元素无法直接定位时,可以通过定位子级元素返回父级来定位元素 写法:/…
//input[@id=“kw”]
//input[contains(@id,“kw”)]
contains表示进一步查找,匹配项模糊查找
//input[contains(text(),“百度”)]
七、selenium三大等待
强制等待
显式等待
隐式等待
八、自动化常见的坑
1、页面元素定位不到,基本都是因为没有添加等待时间或者是元素定位的方式有误造成的
id/name/class/xpath/cssselector单纯的copy很可能会出错,需要通过手写xpath进行定位,再经过验证,确认元素定位的正确性
2、iframe和handles的操作:切换iframe用以操作iframe中的元素,句柄如果不进行切换,则永远在操作第一个句柄(标签页),如果需要操作其他的标签页,则需要切换句柄。
3、自动化测试执行完的标志就是浏览器退出,在实际的自动化中是一定需要断言的。