UI自动化 selenium

Web自动化测试环境搭建步骤

Python开发环境安装Selenium安装浏览器安装浏览器驱动
python:解释器pycharm:编码工具Selenium提供自动化实现的常用方法脚本结果直接体现Chrome、FireFox…保证能够用程序驱动浏览器,实现自动化测试

一、Web自动化测试 Selenium环境搭建

1、Python 安装Selenium

安装:

pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip config get global.index-url

安装包
pip install selenium

查看包
pip show selenium

卸载包
pip uninstall selenium

在这里插入图片描述

升级 pip (可选)

WARNING: You are using pip version 21.1.3; however, version 21.3.1 is available.
You should consider upgrading via the 'd:\python39\python.exe -m pip install --upgrade pip' command.

C:\Users\Administrator>d:\python39\python.exe -m pip install --upgrade pip
Requirement already satisfied: pip in d:\python39\lib\site-packages (21.1.3)
Collecting pip
  Downloading pip-21.3.1-py3-none-any.whl (1.7 MB)
     |████████████████████████████████| 1.7 MB 31 kB/s
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 21.1.3
    Uninstalling pip-21.1.3:
      Successfully uninstalled pip-21.1.3
Successfully installed pip-21.3.1

2、webdriver 驱动

  1. 不同浏览器都有自己独立驱动程序
    不同的版本需要下载匹配其版本的驱动程序
  • Chrome

点击下载chrome的webdriver:
https://googlechromelabs.github.io/chrome-for-testing/

http://npm.taobao.org/mirrors/chromedriver/

不同的Chrome的版本对应的chromedriver.exe 版本也不一样,下载时不要搞错了。如果是最新的Chrome, 下载最新的chromedriver.exe 就可以了。

在这里插入图片描述

http://chromedriver.storage.googleapis.com/index.html?path=95.0.4638.54/

  • Firefox

Firefox驱动下载地址为:

https://github.com/mozilla/geckodriver/releases/

  • IE

IE浏览器驱动下载地址为:
http://selenium-release.storage.googleapis.com/index.html

  • 根据自己selenium版本下载对应版本的驱动即可,python的话,下载里面的IEDriverServerxxx.zip即可,这个是区分32和64位系统的,根据自己的系统下载即可;
  • 需要注意的是,如果要打开IE浏览器的话,需要在浏览器的Internet选项中的安全页里有4个安全选项,Internet、本地Internet、受信任的站点、受限制的站点,这4个里面都有一个启用保护模式,都需要勾选上才可以,还得把驱动的路径加入到环境变量中。

3、导入webdriver模块

  • windows:
    1、解压下载的驱动,获取到chromedriver.exe
    2、将chromedriver.exe复制到项目所在目录即可

实例:
通过程序启动浏览通过程序启动浏览器,并打开百度首页,暂停3秒,关闭浏览器,并打开百度首页,暂停3秒,关闭浏览器
在这里插入图片描述

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time

# 指定浏览器驱动,创建浏览器对象
s = Service("chromedriver.exe")
driver = webdriver.Chrome(service=s)
driver.maximize_window()  # 浏览器最大化
driver.get('https://www.baidu.com/') #输入url
time.sleep(3)
driver.quit()  # 关闭浏览器

二、webdriver api

1 浏览器操作api

# 指定浏览器驱动,创建浏览器对象
s = Service("chromedriver.exe")
driver = webdriver.Chrome(service=s)

------------------------------------
driver.get('https://www.baidu.com/') # 打开指定url
driver.close() # 关闭当前窗口
driver.quit() # 关闭浏览器

driver.maximize_window() # 浏览器最大化
driver.minimize_window() # 浏览器最小化
driver.set_window_size() # 自定义窗口大小 def set_window_size(self, width, height, windowHandle='current') -> dict

driver.refresh()  # 刷新
driver.forward()  # 前进
driver.back()  # 后退

driver.title  # 获取当前title
driver.current_url  # 获取当前url
driver.page_source  # 获取页面源码
driver.find_element(By.ID, 'su').click() # 点击

example:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

import time

# 指定浏览器驱动,创建浏览器对象
s = Service("chromedriver.exe")
driver = webdriver.Chrome(service=s)
driver.maximize_window()  # 浏览器最大化
driver.get('https://www.baidu.com/')
time.sleep(3)

driver.get('https://cn.bing.com/')
driver.refresh()  # 刷新

if '必应' in driver.title and 'bing' in driver.current_url and '必应' in driver.page_source:
    print("pass")
else:
    print("false")

time.sleep(3)
driver.back()  # 后退

time.sleep(3)
driver.forward()  # 前进

driver.minimize_window()  # 浏览器最小化
time.sleep(3)
driver.quit()  # 关闭浏览器

2 元素定位api

方式一

from selenium.webdriver.common.by import By
driver.find_element(by=By.ID, value: Optional[str] = None))

# 返回的数据为所有符合条件的元素对象的列表
 # 定位所有符合条件的元素
driver.find_elements(by=By.ID, value: Optional[str] = None)
class By(object):
    """
    Set of supported locator strategies.
    """

    ID = "id"
    XPATH = "xpath"
    LINK_TEXT = "link text"
    PARTIAL_LINK_TEXT = "partial link text"
    NAME = "name"
    TAG_NAME = "tag name"
    CLASS_NAME = "class name"
    CSS_SELECTOR = "css selector"

id 元素id属性值定位

name 通过元素name定位

CLASS_NAME通过元素class属性值定位

LINK_TEXT 通过元素的文本值定位

PARTIAL_LINK_TEXT通过元素的部分文本值定位

TAG_NAME 通过元素的标签名定位

CSS_SELECTOR 通过元素在HTML页面中的位置定位 使用css

XPATH 通过元素在HTML页面中的位置定位


example:
在这里插入图片描述

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

s = Service(r'D:\pythonProject\testProject001\GUI\webdriver\chromedriver.exe')
driver = webdriver.Chrome(service=s)
driver.maximize_window()  # 浏览器最大化
driver.get('https://www.baidu.com/')

time.sleep(1)

element_1 = driver.find_element(By.ID, 'su')  # 使用id属性值定位
element_2 = driver.find_element(By.CLASS_NAME, 'wrapper_new')  # 使用class属性值定位
element_3 = driver.find_element(By.TAG_NAME, 'input')  # 标签
element_4 = driver.find_element(By.CSS_SELECTOR, '#su')  # 使用css定位元素
element_5 = driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/div[5]/div/div/form/span[2]/input')  # 使用xpath 绝对路径

print(element_1)
print(element_2)
print(element_3)
print(element_4)
print(element_5)

# 完整文本值
query_1 = driver.find_element(By.LINK_TEXT, '新闻')  
print(query_1)

# 部分文本值
query_2 = driver.find_element(By.PARTIAL_LINK_TEXT, "新") 
print(query_2)

driver.quit()

# <selenium.webdriver.remote.webelement.WebElement (session="b1c0f8ebfa7461a185cd84bc48a96781", element="b8f693d7-bfcc-4f10-b941-9f6f3ed671e7")>
# <selenium.webdriver.remote.webelement.WebElement (session="b1c0f8ebfa7461a185cd84bc48a96781", element="2d0c1c52-bb15-48dd-9010-5c8039517b79")>
# <selenium.webdriver.remote.webelement.WebElement (session="b1c0f8ebfa7461a185cd84bc48a96781", element="d2d062e8-bb21-4a58-8185-352d8a8cc184")>
# <selenium.webdriver.remote.webelement.WebElement (session="b1c0f8ebfa7461a185cd84bc48a96781", element="b8f693d7-bfcc-4f10-b941-9f6f3ed671e7")>
# <selenium.webdriver.remote.webelement.WebElement (session="b1c0f8ebfa7461a185cd84bc48a96781", element="b8f693d7-bfcc-4f10-b941-9f6f3ed671e7")>

方式二(已过时)

driver.find_element_by_id(id属性值)
driver.find_element_by_name("passwordA").send_keys("123456")
driver.find_element_by_class_name("telA").send_keys("18611111111")
driver.find_element_by_tag_name("input").send_keys("admin")

# link_text 全部值
driver.find_element_by_link_text(超链接的全部文本内容)
driver.find_element_by_link_text("新浪").click()

# 局部文本:从字符串任意位置开始,一截连续字符集
driver.find_element_by_partial_link_text(超链接的局部文本内容)

# xpath
driver.find_element_by_xpath(xpath表达式)
---

# 查找所有的input标签
inputs = driver.find_elements_by_tag_name("input")
inputs[0].send_keys("admin")
inputs[1].send_keys("123456")
inputs[2].send_keys("13800001111")
inputs[3].send_keys("123@qq.com")

# for input in inputs:
#     input.send_keys("admin")

3 xpath定位函数api

在这里插入图片描述

  • 绝对路径定位:从html开始,到目标元素为止。如:

    /html/body/div[1]/div[2]/div[5]/div[1]/div/form/span[2]/input
    
  • 相对路径定位://*[] 如:
    //开始,后续每个层级都使用/来分隔。
    //fieldset/p[1]/input

    • 属性定位使用@
      //*[@id="su"]或者//input[@id="su"] 代表id为su的input标签。
      //input[@type='submit']
      //*[@value='提交']
    • 属性与逻辑结合:
      //input[@value='提交' and @class='banana']
    • 层级与属性结合:
      //div[@id='test1']/input[@value='提交']
  • 功能函数:

    start-with:定位以指定属性 指定内容 开头的元素。

    '//*[starts-with(@type,"submit")]'
    

    contains:定位指定属性 包含指定内容的元素。

    # 利用局部属性值定位元素
    '//*[contains(@value,"百度一下")]'
    

    text():定位文本值包含指定内容的元素。

    # 利用元素的文本定位元素
    '//*[contains(text(),"百度一下")]'
    

举例:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

s = Service(r'D:\pythonProject\testProject001\GUI\webdriver\chromedriver.exe')
driver = webdriver.Chrome(service=s)
driver.maximize_window()  # 浏览器最大化
driver.get('https://www.baidu.com/')

time.sleep(1)

# 相对路径
element_1 = driver.find_element(By.XPATH, '//div[@id="wrapper"]/div/div/div/div/form/span[2]/input')
print(element_1)

# 绝对路径
element_2 = driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/div[5]/div/div/form/span[2]/input')
print(element_2)

element_3 = driver.find_element(By.XPATH, '//*[starts-with(@type,"sub")]')
print(element_3)

element_4 = driver.find_element(By.XPATH, '//*[contains(@value,"百度一下")]')
print(element_4)
element_5 = driver.find_element(By.XPATH, '//*[contains(text(),"百度一下")]')
print(element_5)

driver.quit()

4 元素交互操作:点击、输入、清空、获取文本、获取元素指定属性

element.click()  --单击

element.send_keys(value) --输入

element.clear() --清空

element.text --获取元素文本

element.size --获取元素大小

element.get_attribute('属性名') --获取元素指定属性的值

element.find_elements() --定位子元素

element.is_displayed()  --判断元素是否可见

element.is_enabled()	--判断元素是否可用

举例
在这里插入图片描述

在这里插入图片描述

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

s = Service(r'D:\pythonProject\testProject001\GUI\webdriver\chromedriver.exe')
driver = webdriver.Chrome(service=s)
driver.maximize_window()  # 浏览器最大化
driver.get('https://cn.bing.com/')

time.sleep(1)

query = driver.find_element(By.ID, 'sb_form_q')  # 定位输入框
query.clear()  # 情况输入框
query.send_keys('python')  # 输入内容

search = driver.find_element(By.ID, 'search_icon')  # 搜索
time.sleep(1)
search.click()  # 点击

if 'Downloads' in driver.page_source:
    print("search finish")
else:
    print("search fail")

# 使用find_elements 获取所有的属性值
rs = driver.find_elements(By.CLASS_NAME, "sh_favicon")
for i in rs:
    print(i.get_attribute('href'))

在这里插入图片描述


5 浏览器操作

- 设置浏览器显示范围
窗口最大化 dirver.maxmize_window()
设置窗口大小 dirver.set_window_size(width, height)
设置窗口位置 dirver.set_window_position(x, y)

- 浏览器显示页面操作
页面后退操作 dirver.back()
页面前置操作 dirver.forword()
设置窗口位置 dirver.refresh()

- 浏览器关闭操作
关闭当前窗口 dirver.close()
关闭浏览器 dirver.quit()

- 获取浏览器信息
获取标题 dirver.title
获取网页地址 dirver.current_url

6 页面交互操作

- 下拉框

1.导包
from selenium.webdriver.support.select import Select

2.创建select对象
select = Select(element)

3.选择选项
select.select_by_index(index) 根据下标
select.select_by_value(value) 根据选项value属性值
select.select_by_visible_text(text) 根据选项文本
<label>
    <select id = 'test'>
        <option>北京</option>
        <option>上海</option>
        <option>天津</option>
        <option>成都</option>
        <option value="cq">重庆</option>
    </select>
</label>

---

import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
import time

s = Service('chromedriver.exe')
driver = webdriver.Chrome(service=s)
path = "file://" + os.path.dirname(__file__) + '\\test.html'
driver.get(path)

element = driver.find_element(By.ID, 'test')
select = Select(element)

# 选项索引
select.select_by_index(1)
time.sleep(3)

# 选项value值
select.select_by_value('cq')
time.sleep(3)

# 选项名称选择
select.select_by_visible_text('成都')

time.sleep(1)
driver.quit()

- 弹出框

获取弹出框对象 
alert = driver.switch_to.alert
alert.text 获取弹出框文本

弹出框处理方法 
alert.accept() 接受弹出框,即点击弹出框的确定
alert.dismiss() 取消弹出框
<script>
    setTimeout((()=>{
        alert('test')
    }),3000)
</script>
---
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time

s = Service('chromedriver.exe')
driver = webdriver.Chrome(service=s)
path = "file://" + os.path.dirname(__file__) + '\\test.html'
driver.get(path)

time.sleep(5)

alert = driver.switch_to.alert
print(alert.text)

# 接受弹出框
alert.accept()

# 取消弹出框
alert.dismiss()

time.sleep(1)
driver.quit()

- 滚动条

定义Js字符串 js = "window.scrollTo(0,1000)"
执行Js字符串 driver.execute_script(js)
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time

s = Service('chromedriver.exe')
driver = webdriver.Chrome(service=s)
path = "file://" + os.path.dirname(__file__) + '\\test.html'
driver.get(path)

time.sleep(3)

js = "window.scrollTo(0,1000)"
driver.execute_script(js)

time.sleep(1)
driver.quit()

- ActionChains鼠标类

点击、右击、双击、悬停 、拖拽等

# 导包 
from selenium.webdriver import ActionChains
# 实例化鼠标对象 
action = ActionChains(driver)

调用鼠标方法
action.move_to_element(element)  鼠标悬停
action.context_click(element)  鼠标右击
action.double_click(element) 鼠标双击
action.drag_and_drop(source, target) 拖拽

执行鼠标操作
action.perform()
调用鼠标方法井不会去执行鼠标操作,必须调用perform才会执行
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
# 导包
from selenium.webdriver import ActionChains

s = Service('chromedriver.exe')
driver = webdriver.Chrome(service=s)
path = "file://" + os.path.dirname(__file__) + '\\test.html'
driver.get(path)

# 实例化鼠标对象
action = ActionChains(driver)
element = driver.find_element(By.CLASS_NAME, 'box')

# 鼠标悬停
action.move_to_element(element)
action.perform()

time.sleep(3)

拖拽

from time import sleep
from selenium import webdriver

# 1、获取浏览器
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select

driver = webdriver.Chrome()
# 2、打开url
driver.get("file:///Users/Documents/web/drop.html")

sleep(3)
# 获取ActionChains对象
action = ActionChains(driver)
div1 = driver.find_element(By.CSS_SELECTOR, "#div1")
div2 = driver.find_element(By.CSS_SELECTOR, "#div2")
action.drag_and_drop(div1, div2).perform()

# 4、关闭浏览器
sleep(3)
driver.quit()

7 元素等待

强制等待

  • 强制等待:time 下的 sleep()方法;
    • 缺点:影响脚本运行效率

隐式等待

  • 隐式等待:implicitly_wait(t)

    • 在指定的时间内等待页面完全加载完成,如果加载完成的时间小于t,剩余时间(t-加载时间)就不再等待;
    • 如果在时间t内未加载完成则报错;
    • 作用范围为全局;
    • 用来提高效率;
    • 定位元素时,如果能定位到元素则直接返回该元素,不触发等待;
    • 如果不能定位到该元素,则间隔一段时间后再去定位元素;
    • 如果在达到最大时长时还没有找到指定元素,则抛出元素不存在的异NoSuchElementException。
    driver.implicitly_wait(10)
    

    例子:

    • 在查找元素之前,WebDriver 会等待最多10秒,以确保元素出现在页面上。
    • 如果元素在10秒内没有找到,WebDriver 将抛出NoSuchElementException异常。因此,通过设置隐式等待时间,我们可以在查找元素时增加一定的容错性,等待元素出现的时间更长一些。
    • 隐式等待适用于整个 WebDriver 实例的生命周期,也就是说,只需设置一次即可,对后续的元素查找操作都会生效
    from selenium import webdriver
    
    # 创建 WebDriver 实例
    driver = webdriver.Chrome()
    
    # 设置隐式等待时间为10秒
    driver.implicitly_wait(10)
    
    # 打开网页
    driver.get("https://www.example.com")
    
    # 查找元素并操作
    element = driver.find_element_by_id("myElement")
    element.click()
    
    # 关闭 WebDriver
    driver.quit()
    

显式等待

  • 显式等待:WebDriverWait()

    • 特殊的隐式等待,等待指定的元素加载完成;
    • 定位 元素时,如果能定位到元素则直接返回该元素,不触发等待;
    • 如果不能定位到该元素,则间隔一段时间后再去定位元素;
    • 如果在达到最大时长时还没有找到指定元素,则抛出超时异常 TimeoutException
    # 导包
    from selenium.webdriver.support.ui import WebDriverWait
    
    # 创建显示等待类对象
    WebDriverWait(driver, timeout, poll_frequency=0.5)
    # poll_frequency 轮询时间 0.5
    
    # 调用utils方法
    until(method):直到...
    class WebDriverWait(object):
        def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
    # driver 浏览器对象
    # timeout 超时时间
    # poll_frequency 扫描间隔时间 一般是0.5
    
        def until(self, method, message=''):
    # until(element)指定加载元素
    

    举例:

    from selenium import webdriver
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.common.by import By
    import time
    
    from selenium.webdriver.support.ui import WebDriverWait
    
    s = Service(r'D:\pythonProject\testProject001\GUI\webdriver\chromedriver.exe')
    driver = webdriver.Chrome(service=s)
    driver.maximize_window()  # 浏览器最大化
    driver.get('https://cn.bing.com/')
    start_time = time.time()
    
    # driver.implicitly_wait(100) # 隐式等待
    
    # 每隔0.5秒扫描元素 sb_form_q 直到元素超时或出现
    # 轮询时间为0.5
    # WebDriverWait() 方法内部,它会将当前的 WebDriver 实例作为参数传递给 lambda 表达式
    query = WebDriverWait(driver, 100, 0.5).until(lambda ele: driver.find_element(By.ID, 'sb_form_q'))
    el = WebDriverWait(driver, 10, 0.5).until(lambda x: x.find_element(By.CSS_SELECTOR, "#username"))
    
    # query = driver.find_element(By.ID, 'sb_form_q')  # 定位输入框
    query.clear()  # 清空输入框
    query.send_keys('python')  # 输入内容
    el.send_keys("admin")
    search = driver.find_element(By.ID, 'search_icon')  # 搜索
    search.click()  # 点击
    
    print(time.time() - start_time)
    
    • WebDriverWait(driver, 100, 0.5):创建一个 WebDriverWait 对象,参数包括 WebDriver 实例 driver、最大等待时间(秒)和轮询间隔时间(秒)。在这里,最大等待时间为 100 秒,轮询间隔时间为 0.5 秒。

    • .until(lambda ele: driver.find_element(By.ID, ‘sb_form_q’)):将 lambda 表达式传递给 until 方法。until 方法会反复调用该 lambda 表达式,直到返回值为 True 或超过最大等待时间。在这里,lambda 表达式接受一个参数 ele,表示待查找的元素。它使用 driver.find_element(By.ID, ‘sb_form_q’) 语句来查找具有 ID 为 ‘sb_form_q’ 的元素。

    • lambda 表达式是一种匿名函数,它可以在代码中创建一个简单的、临时的函数。

      lambda 表达式的语法如下:

      lambda arguments: expression
      其中,arguments 是该匿名函数的参数,可以是一个或多个参数,用逗号分隔。expression 是函数体,表示函数要执行的操作,并返回结果。

      • 它是一种匿名函数,没有函数名。
      • 它可以接受任意数量的参数,包括可选参数和默认参数。
      • 它只能包含一个表达式,而不能包含复杂的语句块。

隐式等待和显示等待对比

隐式等待显示等待
作用域只用设置一次,对全局生效只对指定元素生效
抛出异常NoSuchElementExceptionTimeOutException
使用方法driver.implicitly_wait(timeout)通过WebDriverWait对象
其它必须等待整个页面加载完成只关注指定元素是否加载

8 Frame切换

针对html

  • frameset形式
  • iframe标签形式
切换指定iframe
driver.switch_to.frame(frame_reference)
frame_reference:iframe标签元素对象

恢复默认页面
driver.switch_to.default_content()

举例:

# 获取注册A iframe元素
A = driver.find_element(By.CSS_SELECTOR, "#idframe1")
# 1、切换到A
driver.switch_to.frame(A)

# 2、注册A操作
driver.find_element(By.CSS_SELECTOR, "#username").send_keys("admin")
time.sleep(3)

# 3、回到默认目录 注册.html
driver.switch_to.default_content()

# 4、获取注册B iframe元素
B = driver.find_element(By.CSS_SELECTOR, "#idframe2")
# 5、切换到B
driver.switch_to.frame(B)

# 6、注册B操作
driver.find_element(By.CSS_SELECTOR, "#username").send_keys("admin")

time.sleep(3)

driver.quit()

9 多窗口切换

selenium需要通过窗口的句柄来实现窗口的切换

获取所有窗口句柄
handles = driver.window_handles

切换指定窗口
driver.switch_to.window(handles[n])

例子

driver = webdriver.Chrome()
path = "file://" + os.path.dirname(__file__) + '\\test.html'
driver.get(path)

"""
    为什么要处理多窗口?-- selenium默认焦点在启动窗口,要操作其他窗口必须处理。
    需求:
        1、打开注册示例页面
        2、点击注册A网页链接
        3、填写注册A网页内容
"""

driver.find_element(By.LINK_TEXT, "注册A").click()
handles = driver.window_handles
print("操作之后所有窗口的句柄:", handles)

# 重点:切换窗口
driver.switch_to.window(handles[1])

# 填写注册A网页 用户名
driver.find_element(By.CSS_SELECTOR, "#username").send_keys("admin")

time.sleep(3)
driver.quit()

工具封装

driver = webdriver.Chrome()
driver.implicitly_wait(10)
# 2、打开url
driver.get("file:///Users/lgy/Documents/fodder/web/Register.html")

"""
   需求:
        如何随心所欲切换窗口?
    思路:
        1、获取所有窗口句柄
        2、切换窗口
        3、获取当前所在窗口title
        4、判断title是否为需要的窗口
        5、执行代码
    需求:
        1、打开注册示例页面
        2、点击 注册A网页 注册B网页
        3、在A网页和B网页中输入 对用户名输入 admin 
"""


def switch_window(title):
    # 1、获取所有窗口句柄
    handels = driver.window_handles
    # 2、遍历句柄进行切换
    for handel in handels:
        # 操作
        driver.switch_to.window(handel)
        # 获取当前窗口title 并且 判断是否自己需要的窗口
        if driver.title == title:
            # 操作代码
            print("已找到{}窗口,并且已切换成功".format(title))


title_A = "注册A"
title_B = "注册B"

# 打开注册A和注册B网页
driver.find_element(By.LINK_TEXT, "注册A网页").click()
driver.find_element(By.LINK_TEXT, "注册B网页").click()

# 填写注册A网页 用户名
switch_window(title_A)
driver.find_element(By.CSS_SELECTOR, "#userA").send_keys("admin")

switch_window(title_B)
driver.find_element(By.CSS_SELECTOR, "#userB").send_keys("admin")

# 4、关闭浏览器
sleep(3)
driver.quit()

10 窗口截图

driver.get_screenshot_as_file(imgpath)

imgpath:图片保存路径

举例:

driver = webdriver.Chrome()
# 2、打开url
driver.get("file:///Users/lgy/Documents/fodder/web/%E6%B3%A8%E5%86%8CA.html")
# 3、查找操作元素

driver.find_element(By.CSS_SELECTOR,"#userA").send_keys("admin")
driver.find_element(By.CSS_SELECTOR,"#passwordA").send_keys("123456")
driver.find_element(By.CSS_SELECTOR,"#telA").send_keys("13600001111")
driver.find_element(By.CSS_SELECTOR,"#emailA").send_keys("123@qq.com")
# 截图
driver.get_screenshot_as_file("register.png")
driver.get_screenshot_as_file("error_{}.png".format(time.strftime("%Y_%m_%d %H_%M_%S")))

# 4、关闭浏览器
sleep(3)
driver.quit()

11 验证码\Cookie跳过登陆

手工登陆 - 获取cookie - 脚本添加cookie - 刷新页面

driver.get_cookie(name) --> 获取指定cookie
driver.get_cookies() --> 获取本网站所有本地cookies
driver.add_cookie(cookie_dict) --> 添加cookie
cookie_dict:一个字典对象,必选的键包括:"name" and "value"

举例:

"""
    需求:使用cookie实现百度登录
    依赖cookies: BDUSS
"""
from time import sleep
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
# 添加cookie
data = {"name": "BDUSS", "value": "由于安全问题,暂时删除。"}
driver.add_cookie(data)
driver.get_cookies()
# 暂停3秒
sleep(3)
# 刷新
driver.refresh()
sleep(3)
driver.quit()

三、PO模式

结构

  • base: 存放所有Page页面公共方法
  • page: 将页面封装为对象
  • script: 测试脚本

在这里插入图片描述

base

"""
    Base类:存放所有Page页面公共操作方法!
"""
from selenium.webdriver.support.wait import WebDriverWait


class Base:
    def __init__(self, driver):
        self.driver = driver

    # 查找元素
    def base_find(self, ele, timeout=10, poll_frequency=0.5):
        # 显示等待 -> 查找元素  loc = (By.ID,"userA")  *loc=loc[0],loc[1]
        return WebDriverWait(self.driver, timeout, poll_frequency).until(lambda x: x.find_element(*ele))

    # 输入方法
    def base_input(self, ele, value):
        # 1、获取元素
        el = self.base_find(ele)
        # 2、清空操作
        el.clear()
        # 3、输入内容
        el.send_keys(value)

    # 点击方法
    def base_click(self, ele):
        self.base_find(ele).click()

    # 获取文本值方法
    def base_get_text(self, ele):
        return self.base_find(ele).text

page_login

"""
    模块名:page_模块单词
    类名:大驼峰将模块移植进来,去掉下划线和数字。
    方法:自动化测试当前页面要操作那些元素,就封装那些方法
"""
from selenium.webdriver.common.by import By

# 用户名
from base.base import Base

username = (By.CSS_SELECTOR, "#username")
# 密码
pwd = By.CSS_SELECTOR, "#password"
# 验证码
verify_code = By.CSS_SELECTOR, "#verify_code"
# 登录按钮
login_btn = By.CSS_SELECTOR, "#login"
# 昵称
nick_name = By.CSS_SELECTOR, ".userinfo"


class PageLogin(Base):
    # 输入用户名
    def __page_username(self, value):
        self.base_input(username, value)

    # 输入密码
    def __page_pwd(self, value):
        self.base_input(pwd, value)

    # 输入验证码
    def __page_verify_code(self, value):
        self.base_input(verify_code, value)

    # 点击登录按钮
    def __page_click_login_btn(self):
        self.base_click(login_btn)

    # 获取昵称
    def page_get_nickname(self):
        return self.base_get_text(nick_name)

    # 组合业务方法 (强调:测试业务成调用此方法,便捷。)
    def page_login(self, phone, password, code):
        self.__page_username(phone)
        self.__page_pwd(password)
        self.__page_verify_code(code)
        self.__page_click_login_btn()

test script

import os
import unittest

from selenium import webdriver

from page.page_login import PageLogin


class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.path = "file://" + os.path.dirname(__file__) + '\\test.html'
        self.driver.get(self.path)
        self.login = PageLogin(self.driver)

    def tearDown(self) -> None:
        self.driver.quit()

    def test01_login(self,phone="13600001111",password="123456",code="8888"):
        # 调用登录业务
        self.login.page_login(phone,password,code)
        # 断言
        nickname = self.login.page_get_nickname()
        print("nickname:", nickname)

数据驱动

1、UI自动化测试中数据驱动的核心是:

  • 利用参数化技术使用同样的测试步骤来执行不同的测试数据,验证各种测试情况
  • 将测试数据和测试脚本分离,编写完成操作脚本后,将重点放到数据的维护和构建上

在这里插入图片描述

/data/login.json

{
  "login": [
    {
      "desc":"登录成功",
      "phone": "13600001111",
      "password": "123456",
      "code": "8888",
      "expect_text": "13600001111"
    }
  ]
}

util.py

import json
# 读取json工具
import os


def read_json(filename, key):
    filepath = os.path.dirname(__file__) +os.sep + '..'+os.sep + "data" + os.sep + filename
    arr = []
    with open(filepath, "r", encoding="utf-8") as f:
        for data in json.load(f).get(key):
            arr.append(tuple(data.values())[1:])
        # 切片表示对元组进行切片操作,从索引为1 的位置开始截现到未尾,这样做是为了去除元组的第一个元素。
        return arr


if __name__ == '__main__':
    """
        [(),()]
    """
    print(read_json("login.json", "login"))

script/test01.py

import os
import unittest
from selenium import webdriver
from page.page_login import PageLogin
from parameterized import parameterized
from util import read_json


class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.path = "file://" + os.path.dirname(__file__) + '\\test.html'
        self.driver.get(self.path)
        self.login = PageLogin(self.driver)

    def tearDown(self) -> None:
        self.driver.quit()

    # def test01_login(self,phone="13600001111",password="123456",code="8888"):
    @parameterized.expand(read_json("login.json", "login"))
    def test01_login(self, phone, password, code, expect_text):
        # 调用登录业务
        self.login.page_login(phone, password, code)

        # 断言
        nickname = self.login.page_get_nickname()
        print("nickname:", nickname)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值