主要是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')
系统d窗
# alert元素 element = driver.find_element_by_xpath('//*[@id="alerta"]').click() #alert = driver.switch_to_alert() # 切换到d窗 alert = driver.switch_to.alert print(alert.text) sleep(3) # 去除d窗 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)
验证码
# 验证码处理方式 # 去掉,设置万能验证码,验证码识别技术,记录cookiecookie_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 -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__.pyfrom 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)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)