|
主要是selenium+pytest+POM
一、selenium
初始框架:
# 导入模块
from selenium import webdriver
from time import sleep
# 实例化浏览器对象
driver = webdriver.Chrome()
# 打开网页
driver.get('***.html')
# 展示效果
sleep(3)
# 关闭页面
driver.quit()
元素定位
# 使用id定位
element = driver.find_element_by_id('xx')
# 使用name定位
element = driver.find_element_by_name('xx')
# class_name根据元素class属性定位元素
element = driver.find_element_by_class_name('xx')
# tag_name:标签名
element = driver.find_element_by_tag_name('xx')
# 使用link_text定位访问超链接
l = driver.find_element_by_link_text('xx')
# 只需要超链接的部分文本信息
pl = driver.find_element_by_partial_link_text('xx')
除了id唯一外,其他都有重复的可能,所以其他要保证唯一性
元素信息
element.size, element.text, element.get_attribute('class'), element.is_displayed(),element.is_enabled(), element.is_selected()
元素操作方法
element.send_keys('xx')、element.click()
driver操作
driver.back()
driver.forward()
driver.refresh()
driver.close()
driver.quit()
driver.title
driver.current_url
定位一组元素
usernames = driver.find_elements_by_name('xxx')
for username in usernames:
username.send_keys('xxx')
sleep(3)
XPath
# XPath
# 路径:定位
# 利用元素属性:定位
# 属性与逻辑结合:定位
# 层级与属性结合:定位
# 方法名:find_element_by_xpath(xpath)
# 绝对路径:从最外层元素到指定元素之间所有经过元素层级的路径,以/html开始
# 相对路径:匹配任意层级的元素,不限制元素的位置,以//开始
# 利用元素属性策略
# 语法://标签名[@属性名='属性值']
# 语法: //*[@属性名='属性值' and @属性名='属性值']
# 层级与属性结合
# //*[@id='p1']/input
# 延伸://*[text()="xxx"] 文本内容是xxx的元素
# //*[contains(@attribute,'xxx')] 属性中含有xxx的元素
# //*[starts-with(@attribute, 'xxx')] 属性以xxx开头
CSS
# 推荐使用CSS比Xpath快
# CSS定位常用策略:
# 1. id选择器 #id
# 2. class选择器 .class
# 3. 元素选择器 element(标签)
# 4. 属性选择器 [属性=值]
# 5. 层级选择器
# 方法:find_element_by_css_selector
# 层级:父子:>,祖辈和后代:空格
# CSS延伸
# input[type^='p'] 以p开头
# input[type$='d'] 以d结尾
# input[type*='w'] 包含w的
下拉框
select = Select(wb.find_element_by_id('selectA'))
select.select_by_index(2)
元素等待
# 在定位页面元素时如果未找到,会在指定时间内一直等待的过程
# 为什么设置?1. 网络速度慢 2. 电脑配置低 3. 服务器处理请求慢
# 隐式等待和显示等待
# 隐式等待:如果能找到元素就不等待,如果找不到就隔一段时间(默认值)定位,如果达到最大时间还没找到,就抛出异常
# driver.implicitly_wait(timeout)
# timeout为等待最大时长,单位为s
# 隐式等待为全局设置,设置一次作用于所有元素
# 当隐式等待被激活时,虽然目标元素已经出现了,但是还是会因为页面内其他元素未加载完成而继续等待,进而增加代码执行时间
# 显示等待,如果能找到元素就不等待,如果找不到就隔一段时间(默认值)定位,如果达到最大时间还没找到,就抛出异常
element = WebDriverWait(driver, 10, 1).until(lambda x: x.find_element_by_id("userA"))
element.send_keys('admin') #显示
frame
# 当确定id却提示没有定位到元素的时候,可以考虑是不是有frame
# 如果有frame包含的要先获取frame
driver.switch_to_frame('idframe1')
多窗口
# 当点击超链接的时候,切换到另一个窗口的时候要切换handle,每次调用的时候每个窗口都会创建自己独立的handle
hand = driver.current_window_handle
driver.switch_to.window(hand)
截图
driver.get_screenshot_as_file('./1.png')
系统弹窗
# alert元素
element = driver.find_element_by_xpath('//*[@id="alerta"]').click()
#alert = driver.switch_to_alert()
# 切换到弹窗
alert = driver.switch_to.alert
print(alert.text)
sleep(3)
# 去除弹窗
alert.accept() # 同意
键盘操作
# 删除:BACK_SPACE, SPACE 空格, TAB 制表, ESCAPE 回退, ENTER 回车, CONTROL 'a' 全选, CONTROL 'c' 复制
str = username.send_keys(Keys.CONTROL, 'c')
password.send_keys(Keys.CONTROL, 'v')
鼠标操作
username = driver.find_element_by_id('userA')
action.context_click(username)# 右键,鼠标右键只能展示菜单内容,菜单中的元素无法操作
action.perform() # 该方法必须调用
sleep(3)
# 左键
action.click(username)
action.perform() # 该方法必须调用
sleep(2)
# 双击
username.send_keys("admin")
action.double_click(username)
action.perform()
sleep(3)
# 拖拽, 起点元素和终点, 主要用于滑块验证码(以前)
ll = driver.find_element_by_link_text('访问 新浪 网站')
action.drag_and_drop(ll, username)
action.perform()
sleep(3)
# 悬停
element = driver.find_element_by_xpath('//*[@id="zc"]/fieldset/button')
action.move_to_element(element)
action.perform()
sleep(3)
验证码
# 验证码处理方式
# 去掉,设置万能验证码,验证码识别技术,记录cookie
cookie_value = {'name':'BDUSS',
'value':'cookie'}
driver.add_cookie(cookie_value)
driver.refresh()
滚动条
# selenium没有专门操作滚动条的,但是可以用js代码来实现
js = 'window.scrollTo(0, 1000)'
driver.execute_script(js)
sleep(3)
js = 'window.scrollTo(0, 0)'
driver.execute_script(js)
sleep(3)
Pytest(python自动化测试框架)
# 函数形式 pytest -s 1.py -s表示输出打印信息
def test_func():
print('我是测试函数')
# 测试类 类名必须以Test开头
class Test_demo(object):
def test_method1(self):
print('测试方法1')
def test_method2(self):
print('测试方法2')
# 主函数方法执行
import pytest
if __name__ == "__main__":
pytest.main(['-s', './2.py'])
class Test_demo():
def setup_class(self):# 类级别
print('start')
def teardown_class(self):# 类级别
print('end')
def setup(self):# 方法级别
print('开始')
def test_1(self):
print('1')
def test_2(self):
print('2')
def teardown(self):# 方法级别
print('结束')
# 控制顺序
import pytest
class Test_demo():
def setup_class(self):# 类级别
print('start')
def teardown_class(self):
print('end')
def setup(self):
print('开始')
@pytest.mark.run(order=2)# 控制执行顺序
def test_1(self):
print('1')
@pytest.mark.run(order=1)
@pytest.mark.skip('noreason') #跳过操作
def test_2(self):
print('2')
assert 1==2
@pytest.mark.parametrize('password, username', [('123456', 'li'), ('4444', 'e')]) #参数
def test_canshu(self, password, username):
print(username, password)
def teardown(self):
print('结束')
pytest执行顺序就是定义的顺序,而unittest顺序是根据ASCII码来的
pytest.ini
[pytest]
test_path=./
addopts=-s
--html=./test.html # 测试报告
--reruns 2 # 重跑
python_files=*.py
python_classes=Test*
python_functions=test*
断言直接使用assert
PO设计模式
Base:base.py get_driver.py
# base.py
from selenium.webdriver.support.wait import WebDriverWait
import time
class Base:
def __init__(self, driver):
self.driver = driver
def base_find_element(self, loc, timeout=30, poll=0.5):
return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(lambda x:x.find_element(*loc))
def base_click(self, loc):
self.base_find_element(loc).click()
def base_get_value(self, loc):
return self.base_find_element(loc).get_attribute('value')
def base_get_img(self):
self.driver.get_screenshot_as_file('./{}.png'.format(time.strftime('%Y_%m_%d_%H_%M_%S')))
#get_driver.py
from selenium import webdriver
import PO设计模式.v4.page as page
class GetDriver:
driver = None
@classmethod
def get_driver(cls):
if cls.driver == None:
cls.driver = webdriver.Chrome()
cls.driver.maximize_window()
cls.driver.get(page.url)
return cls.driver
@classmethod
def quit_driver(cls):
if cls.driver:
cls.driver.quit()
cls.driver = None
data: 主要放json数据
test.json
page:__init__.py、以及各种对页面的操作
#__init__.py
from selenium.webdriver.common.by import By
url='http://cal.apple886.com/'
xx = By.CSS_SELECTOR,"xx"
page: xx.py
from time import sleep
from PO设计模式.v4 import page
from PO设计模式.v4.base.base import Base
from selenium.webdriver.common.by import By
class xx(Base):
def page_click_xx(self):
self.base_click(page.xx)
...
scripts:放各种test类
import pytest
from PO设计模式.v4.base.get_driver import GetDriver
from PO设计模式.v4.page.page_cal import xx
from PO设计模式.v4.tool.read_json import read_json
def get_data():
data = read_json("xx.json")
# print(data)
"""
期望数据格式:[(xx,xx), (xx,xx), (xx,xx)]
"""
list = []
for n in data.values():
list.append((n["a"], n["b"], n["expect_result"]))
return list
class Testxx():
# driver = None
@classmethod
def setup_class(cls):
cls.driver = GetDriver().get_driver()
cls.xx = Pagexx(cls.driver)
@classmethod
def teardown_class(cls):
GetDriver().quit_driver()
@pytest.mark.parametrize('a,expect_result', get_data())
def test_add_cla(self,a,expect_result):
self.xx.page_add_xx(a)
????????result = ...
try:
self.assertEqual(result,str(expect_result))
except:
raise
finally:
????????????pass
if __name__ == '__main__':
pytest.main('-s', 'test_xx.py', "--html='./result.html'")
tool:read_json.py
import json
def read_json(filename):
filepath ="../data/"+ filename
with open(filepath,"r",encoding="utf8") as f:
return json.load(f)
|