自动化测试之web自动化(Selenium)

1、介绍

自动化测试概念:让程序代替人为去验证程序功能的过程,本质上就是用来让将人的精力从重复性的工作中解放出来

优点:

  1. 减少人工的重复性劳动
  2. 执行速度快
  3. 可以重复利用
  4. 生成测试报告,有利于决策

缺点:

  1. 对测试人员的技能要求高

应用场景:

  1. 单元测试
  2. 回归测试:项目在发新版本之后对项目之前的功能进行验证
  3. 压力测试:可以理解多用户同时去操作软件,统计软件服务器处理多用户请求的能力
  4. 兼容性测试:不同浏览器(IE、Firefox、Chrome)等等

主流测试工具:

  • QTP(收费): QTP是商业的功能测试工具,收费,支持web,桌面自动化测试。
  • Selenium(开源)【本阶段学习】: Selenium是开源的web自动测试工具,免费,主要做功能测试。
  • Jmeter(开源、Web、接口、性能, 接口测试使用): Jmeter是由Apache公司使用Java平台开发的一款测试工具,支持(Web、接口测试、性能测试)。
  • Loadrunner(收费、Web、性能): Loadrunner是商业性能测试工具,收费,功能强大,适合做复杂场景的性能测试
  • Robot framework: Robot Framework是一个基于Python可扩展地(关键字驱动)的测试自动化框架;

2、Web自动化:Selenium

2.1、Selenium介绍

  • Selenium是一个用于Web应用程序测试的工具,可以直接调用浏览器,它支持所有主流的浏览器。
  • 最初是为网站自动化测试而开发的,但却被很多爬虫爱好者发扬光大

  • 官网:https://www.selenium.dev/

特点:

  1. 开源软件:源代码开放可以根据需要来增加工具的某些功能
  2. 跨平台:linux 、windows 、mac
  3. 核心功能:就是可以在多个浏览器上进行自动化测试
  4. 多语言:Java、Python、C#、JavaScript、Ruby等
  5. 成熟稳定:目前已经被google , 百度, 腾讯等公司广泛使用
  6. 功能强大:能够实现类似商业工具的大部分功能,因为开源性,可实现定制化功能

2.1.1、WebDriver

Webdriver 是一种用于控制浏览器的程序,不同的浏览器有不同的 webdriver

  1. Chrome (ChromeDriver)【本阶段学习使用】
  2. IE(InternetExplorerDriver)
  3. Opera(OperaDriver)
  4. Firefox (FirefoxDriver)
  5. safari(SafariDriver)
  6. HtmlUnit (HtmlUnit Driver)

webdriver 提供了对外的接口,其他程序通过这些接口控制 webdriver 与浏览器的交互。例如:我们可以写 python 程序来调用 webdriver 的接口。实际上从其他程序的角度看,webdriver 就是充当了和浏览器交互的一个桥梁。

说明:

  • Firefox、Chrome:对元素定位和操作有良好的支持,同时对JavaScript支持也非常好。
  • IE: 只能在windows平台运行,所有浏览器中运行速度最慢
  • HtmlUnit:无GUI(界面)运行,运行速度最快;

2.1.2、Selenium 执行过程

python代码--> selenium 封装的 python 接口--> WebDriver 提供接口--> 浏览器

2.1.3、环境搭建

  • 基于python环境搭建

pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple

注意: 在安装selenium时,前提是Python3.5以上版本安装完毕且能正常运行

  • 安装适配浏览器版本的webdriver驱动

国内不能直接访问Chrome官网,可以在ChromeDriver仓库中下载或者https://npm.taobao.org/mirrors/chromedriver

2.2、元素定位

2.2.1、WebDriver元素定位的简单方式

selenium页面元素定位的方法,是在selenium中可以通过多种方式来定位标签,返回标签元素对象:

  • 通过 id 属性定位 : find_element_by_id
  • 通过 name 属性定位 : find_element_by_name
  • 通过 class 属性定位 : find_element_by_class_name
  • 通过标签名定位 : find_element_by_tag_name
  • 通过内容定位 a 标签(绝对匹配) : find_element_by_link_text
  • 通过内容定位 a 标签(模糊匹配) : find_element_by_partial_link_text
from selenium.webdriver import Chrome
import traceback

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome(executable_path='./chromedriver')

# 控制浏览器访问url地址
# file://{本地文件绝对路径}
driver.get('file:///home/python/code/unit_testing/selenium_code/test.html')  # 打开本地 html 文件

try:
    print(driver.find_element_by_id('username')) # 通过 id 属性定位
    driver.find_element_by_name('password2')  # 通过 name 属性定位
    driver.find_element_by_class_name('input-password') # 通过 class 属性定位
    driver.find_element_by_tag_name('ul') # 通过标签名定位
    driver.find_element_by_link_text('标签') # 通过内容定位 a 标签(绝对匹配)
    driver.find_element_by_partial_link_text('Optimization')  # 通过内容定位 a 标签(模糊匹配)
except Exception:
    print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()
View Code
  • Chrome(executable_path='./chromedriver')中executable参数指定的是下载好的chromedriver文件的路径
  • 要在代码中尽量保证driver.quit()能够成功执行,进而关闭driver退出模拟浏览器;不然将在操作系统中残留进程,对系统造成不必要的压力

2.2.2、xpath方式

  1. XPath即为XML Path的简称,它是一种用来确定XML/HTML文档中某部分位置的语言
  2. XPath文档:http://www.w3school.com.cn/xpath/index.asp

1、xpath路径

html,xml 中的元素可以嵌套其他元素,但是根元素只有一个。我们可以这种嵌套关系看成路径。路径分绝对路径和相对路径:

  • 绝对路径:从根元素到指定元素之间所有经过元素层级路径,绝对路径以 "/" 开始,例如: input 的绝对路径是: /html/body/form/input
  • 相对路径:从任何元素开始到该元素的路径,相对路径以 "//" 开始,例如: 用户名输入框标签的相对路径有: //form/input//body/form/input

2、xpath定位

xpath 定位是结合路径来进行定位的,分为绝对定位和相对定位。定位过程中还可以结合元素的属性值。

定位方法:find_element_by_xpath

  • 纯路径定位
    • 绝对定位:find_element_by_xpath("/html/body/form/input")
    • 相对定位:find_element_by_xpath("//div/ul/li/a")
  • 结合属性定位
    • 单个属性:find_element_by_xpath("//input[@type='text']")
    • 多个属性:driver.find_element_by_xpath("//input[@type='text' and @name='username']")
  • 选择上一级元素
    • find_element_by_xpath("//input/.."):返回的是 form 元素
  • 满足条件的多个元素,选择其中的一个
    • driver.find_element_by_xpath("//ul/li[1]"):有多个 li 满足条件,选择其中一个,通过下标来完成,下标从 1 开始
    • driver.find_element_by_xpath("//ul/li[last()]"):选择最后一个
    • driver.find_element_by_xpath("//ul/li[last()-1]"):选择倒数第二个
from selenium.webdriver import Chrome
import traceback

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome(executable_path='./chromedriver')

# 控制浏览器访问url地址
# file://{本地文件绝对路径}
driver.get('file:///home/python/code/unit_testing/selenium_code/test.html')  # 打开本地 html 文件

try:
    print(driver.find_element_by_xpath('/html/body/form/input'))
    print(driver.find_element_by_xpath('//div/ul/li'))

    print(driver.find_element_by_xpath('//form/input[@name="password"]'))
    print(driver.find_element_by_xpath('//form/input[@name="password2" and @type="text"]'))

    print(driver.find_element_by_xpath('//li/..'))

    print(driver.find_element_by_xpath('//ul/li[1]'))
    print(driver.find_element_by_xpath('//ul/li[last()]'))
    print(driver.find_element_by_xpath('//ul/li[last()-1]'))
except Exception:
    print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()
View Code

2.2.3、CSS方式

定位方法:find_element_by_css_selector

  1. 在selenium中极力推荐CSS定位,因为它比XPath定位速度要快
  2. CSS 选择器语法非常强大,在这里我们只学习在测试中常用的几个
driver.find_element_by_css_selector('#username') # 通过 id
driver.find_element_by_css_selector('.input-text') # 通过 class
driver.find_element_by_css_selector('form') # 通过标签名
driver.find_element_by_css_selector('input[type="password"]') # 通过标签属性
driver.find_element_by_css_selector('div>ul') # 通过父子元素
View Code

2.2.4、查询多个元素

  • 通过 id 属性定位 : find_elements_by_id
  • 通过 name 属性定位 : find_elements_by_name
  • 通过 class 属性定位 : find_elements_by_class_name
  • 通过标签名定位 : find_elements_by_tag_name
  • 通过内容定位 a 标签(绝对匹配) : find_elements_by_link_text
  • 通过内容定位 a 标签(模糊匹配) : find_elements_by_partial_link_text
  • 通过 xpath : find_elements_by_xpath
  • 通过 CSS 选择器: find_elements_by_css_selector

和选择单个元素的字面区别就是多了个 s

区别:调用这类方法,会返回一个列表,没有找到元素则返回空列表,查找单个元素的方法会在找不到元素时抛出 NoSuchElementException 异常

2.3、元素等待

概念:WebDriver定位页面元素时如果未找到,会在指定时间内一直等待的过程。

元素等待的必要性:

当使用脚本定位元素或去验证程序的运行状态时,由于资源受限或网络延迟引起的响应速度太慢,导致要定位的元素还未加载到页面。

例如:页面是通过 Ajax 发起请求,但是网络有延迟,提交按钮点击完后,页面等待服务器的返回结果来更新页面,那么在这期间,测试代码是不能够直接去查找预期的元素的。

元素等待类型

  1. 显式等待
  2. 隐式等待

2.3.1、显式等待

概念:使 WebDriver 等待某个条件成立,否则在达到最大时长时抛出超时异常(TimeoutException)

1、WebDriverWait 类

from selenium.webdriver.support.wait import WebDriverWait

参数:

  • driver: webdriver对象
  • timeout: 等待多长时间
  • poll_frequency: 每次执行失败时休眠多长时间

2、调用方法

WebDriverWait.util(method, message=''):

参数说明:

  • method 函数,这个函数必须定义一个参数,接受 driver 对象。例如: def contain_title(driver)
  • message 如果等待失败,message 作为消息抛出

返回值:如果找到,返回找到元素的对象

from selenium.webdriver import Chrome
import traceback
from selenium.webdriver.support.wait import WebDriverWait
driver = Chrome('./chromedriver')

# 3. 打开网址
# file://{本地网址绝对路径}
driver.get('http://www.baidu.com')


try:
    # time.sleep(2)
    # 1. 指定最长的等待时间,指定检测until函数的时间
    # driver对象,最长等待5s, 如果没有找到,每隔0.5s, 检测until()指定的函数,如果5s都没有找到,抛出异常
    wait_driver = WebDriverWait(driver, 5, 0.5)

    # WebDriverWait.until(), 需要传入一个函数名, 这个函数,参数为Chrome类型
    el = wait_driver.until(lambda temp: temp.find_element_by_tag_name('html'))
    print(el)

except Exception as e:
    # print(e) # 只打印错误信息
    print(traceback.format_exc()) # 有错误路径显示
finally:
    # 不管有没有异常,都保证driver可以关闭
    driver.quit()
View Code

2.3.2、隐式等待

如果定位某一元素定位失败,那么就会触发隐式等待有效时长,如果在指定时长内加载完毕,则继续执行,否则抛出 NoSuchElementException 异常。

调用方法

driver.implicitly_wait(10)
from selenium.webdriver import Chrome
from selenium.webdriver.support.wait import WebDriverWait
import traceback
import time

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome(executable_path='./chromedriver')

# 控制浏览器访问url地址
driver.get('https://www.baidu.com')

driver.implicitly_wait(5) # 隐式等待

try:
    driver.find_element_by_id('kw')

except Exception as e:
    print('type = ', type(e))
    # print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()
View Code

2.4、浏览器常用属性和方法

2.4.1、属性

  • driver.name:当前浏览器的名字
  • driver.title:当前网页的标题
  • driver.current_url:当前网页的
  • url driver.page_source:当前网页的源码

2.4.2、方法

driver.close() # 关闭当前窗口
driver.quit() # 关闭浏览器

# 历史
driver.back() # 历史后退
driver.forward() # 历史前进

# 刷新页面
driver.refresh() # 刷新页面

# 窗口大小位置
driver.maximize_window() # 浏览器最大化
driver.fullscreen_window() # 浏览器全屏
driver.minimize_window() # 浏览器最小化
View Code

2.4.3、窗口截图

说明:自动化脚本是由程序去执行的,因此有时候打印的错误信息并不是十分明确。如果在执行出错的时候对当前窗口截图保存,那么通过图片就可以非常直观地看到出错的原因。

在WebDriver类库中,提供了截图方法,我们只需要调用:

driver.get_screenshot_as_file(文件路径.png)

from selenium.webdriver import Chrome

driver = Chrome('./chromedriver')

# 3. 打开网址
# file://{本地网址绝对路径}
driver.get('https://www.baidu.com')
driver.maximize_window()

driver.implicitly_wait(2)

# 截图保存
driver.get_screenshot_as_file('error.png')

driver.quit()
View Code

2.4.4、执行 javascript 代码

有时候我们需要在特定页面中执行 javascript 脚本,通过 driver.execute_script(js代码)

from selenium.webdriver import Chrome
from selenium.webdriver.support.wait import WebDriverWait
import traceback
import time

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome('./chromedriver')

# 控制浏览器访问url地址
driver.get('https://www.baidu.com')

# driver.maximize_window() # 最大化窗口

# 执行js代码
driver.execute_script("alert('hello world')")

time.sleep(3) # 延时3s

# 退出浏览器
driver.quit()
View Code

2.4.5、cookie

  • driver.get_cookies():获取所有的 cookie
  • driver.get_cookie(name):获取指定的 cookie
  • driver.delete_cookie(name):删除指定的 cookie
  • driver.delete_all_cookies():删除所有的 cookie
  • driver.add_cookie(cookie_dict):添加一个 cookie cookie_dict {"name":"xxx","value":"xxx"} 可选的 key 是 "path", "domain", "secure", "expiry"
from selenium.webdriver import Chrome
from selenium.webdriver.support.wait import WebDriverWait
import traceback
import time

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome('./chromedriver')

# 控制浏览器访问url地址
driver.get('http://www.baidu.com')

for cookie in driver.get_cookies():
    print("%s -> %s" % (cookie['name'], cookie['value']))

print('================添加 cookie=====================')

driver.add_cookie({"name": "my-cookie", "value": "my-value"})

for cookie in driver.get_cookies():
    print("%s -> %s" % (cookie['name'], cookie['value']))

print('================删除 cookie=====================')
driver.delete_cookie('my-cookie')

# print(driver.get_cookies())
for cookie in driver.get_cookies():
    print("%s -> %s" % (cookie['name'], cookie['value']))

time.sleep(2)
driver.quit() # 退出浏览器
View Code

2.5、元素常用属性和方法

2.5.1、模拟鼠标单击

点击元素,通过调用 click() 方法

from selenium.webdriver import Chrome
import traceback
import time

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome(executable_path='./chromedriver')

# 控制浏览器访问url地址
# file://{本地文件绝对路径}
driver.get('file:///home/python/code/unit_testing/selenium_code/test.html')  # 打开本地 html 文件

try:
    el = driver.find_element_by_id('button')
    for i in range(10): # 模拟鼠标单击
        el.click()
        time.sleep(1)
except Exception:
    print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()
View Code

2.5.2、输入框元素填充数据和清空

如果是输入框元素,可以通过 send_keys(字符串) 将该字符串填充到输入框中,通过 clear() 清空输入框

from selenium.webdriver import Chrome
import traceback
import time

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome(executable_path='./chromedriver')

# 控制浏览器访问url地址
# file://{本地文件绝对路径}
driver.get('file:///home/python/code/unit_testing/selenium_code/test.html')  # 打开本地 html 文件

try:
    el = driver.find_element_by_id('username')

    time.sleep(1)
    # 填充数据
    el.send_keys("我的用户名")
    time.sleep(2)

    # 清空数据
    el.clear()
    time.sleep(1)
except Exception:
    print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()
View Code

2.5.3、获取标签属性

html 元素有一些属性,这些属性通过 get_attribute(属性名) 来获取

import time
from selenium.webdriver import Chrome

driver = Chrome('./chromedriver')
driver.get('file://{文件绝对路径}')

el = driver.find_element_by_tag_name('body')

# 获取body里面的内置html属性信息
print(el.get_attribute('innerHTML'))
View Code

2.5.4、行为链

WebDriver 中将元素的点击和发送表单数抽象位行为链,行为链中可以包含一个以上的动过,常见行为如下:

  • 鼠标单击
  • 鼠标右击
  • 鼠标双击
  • 鼠标拖动
  • 鼠标指针移动
  • 按键按下
  • 按键松开

1、ActionChains的使用

from selenium.webdriver.common.action_chains import ActionChains

使用步骤:

  1. 实例化 ActionChains
  2. 通过方法添加要执行的行为,可以添加多个,并且可以链式添加,这一步是保存要执行的行为,并不会执行。例如
  3. 调用 Actionchains 对象的 perform() 执行上一步添加的行为
from selenium.webdriver import Chrome
import traceback
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time

# 通过指定chromedriver的路径来实例化driver对象
driver = Chrome(executable_path='./chromedriver')

# 控制浏览器访问url地址
# file://{本地文件绝对路径}
driver.get('file:///home/python/code/unit_testing/selenium_code/test.html')  # 打开本地 html 文件

# 实例化 ActionChains 对象
actions = ActionChains(driver)

try:

    # 找到输入框元素
    input_el = driver.find_element_by_id('username')

    # 鼠标移动到表单元素上-->执行点击-->按下shift-->按下 a -->松开 shift-->松开 a
    # 相当于给输入框驶入一个字母 Aa
    actions.move_to_element(input_el).click().key_down(Keys.SHIFT).key_down('a').key_up(Keys.SHIFT).key_up('a')
    # 执行行为链
    actions.perform()
    time.sleep(2)

except Exception:
    print(traceback.format_exc())
finally:
    # 退出浏览器
    driver.quit()
View Code

2、方法参考

  • reset_actions(self) : 清空行为链
  • click(self, on_element=None): 鼠标点击
  • click_and_hold(self, on_element=None) : 鼠标按下
  • release(self, on_element=None) : 松开鼠标
  • context_click(self, on_element=None) : 鼠标右击
  • double_click(self, on_element=None) : 鼠标双击
  • drag_and_drop(self, source, target) : 拖动元素,source 被拖动元素,target 表示被拖动到那个元素中
  • drag_and_drop_by_offset(self, source, xoffset, yoffset) : 拖动元素,给定x,y 轴偏移
  • key_down(self, value, element=None) : 按键按下
  • key_up(self, value, element=None) : 按键松开
  • move_by_offset(self, xoffset, yoffset) : 鼠标箭头移动,给定 x,y 轴偏移
  • move_to_element(self, to_element) : 鼠标移动到某个元素中心
  • move_to_element_with_offset(self, to_element, xoffset, yoffset) : 鼠标移动到元素内的 x,y 轴位置
  • send_keys(self, *keys_to_send): 发送多个按键,也可以是一个字符串
  • send_keys_to_element(self, element, *keys_to_send) :

2.6、窗口、frame、警告框

2.6.1、frame

frame:HTML页面中的一种框架,主要作用是在当前页面嵌套另一页面页面; (HTML语言中,<frame></iframe>标签为表单框架)

webdriver只能访问一个页面,默认是外层页面,如果要访问嵌套的页面,必须切换当前到嵌套页面中。

切换

driver.switch_to.frame(frame 元素)

driver.switch_to.default_content() 切换到外层页面
from selenium import webdriver

driver = Chrome('./chromedriver')
driver.get('https://www.w3school.com.cn/tiy/t.asp?f=html_elements_select')

# 找到 iframe 元素
frame=driver.find_element_by_tag_name('iframe')
# 切换到 iframe 中
driver.switch_to.frame(frame)
# 查找 select 元素
select=driver.find_element_by_tag_name('select')
# 打印元素的 innerHTML 属性
print(select.get_attribute('innerHTML'))
View Code

2.6.2、多窗口

说明:在HTML页面中,经常有a标签也就是超链接,这些链接在被执行时,有的会在新的窗口打开链接;

切换

说明:在WebDriver中封装了获取当前窗口句柄方法和获取所有窗口句柄的方法以及切换指定句柄窗口的方法;(句柄:英文handle,窗口的唯一识别码)

driver.switch_to.window(窗口句柄)
from selenium import webdriver
import time

driver = Chrome('./chromedriver')
driver.get('http://www.baidu.com')
# 打开新的窗口
driver.find_element_by_link_text('新闻').click()
# 查看所有窗口句柄
print(driver.window_handles)
# 查看当前的窗口句柄
print(driver.current_window_handle)
# 切换窗口
driver.switch_to.window(driver.window_handles[0])
time.sleep(5)
# 切回窗口
driver.switch_to.window(driver.window_handles[1])
View Code

2.6.3、警告框处理

说明:WebDriver中对处理警告框的操作,有专用的处理方法;

提示: HTML中常用的对话框有三种,处理的方法都一样

  1. alert
  2. confirm
  3. prompt

1、调用方法

# 获取当前窗口的警告框 
alert=driver.switch_to.alert

2、警告框处理方法

  1. accept : 接受对话框选项
  2. dismiss : 取消对话框选项
from selenium import webdriver
import time

driver = Chrome('./chromedriver')
driver.get('http://www.baidu.com')

# 打开一个警告框
driver.execute_script("alert('hello')")
# 切换到警告框
alert = driver.switch_to.alert

# 关闭警告框
alert.dismiss()
View Code

2.7、下拉框

说明:下拉框就是HTML中<select>元素;

2.7.1、Select类

from selenium.webdriver.support.select import Select

说明:Select 类是 WebDriver 为解决 select 标签定位诞生的,此类定位的是 select 标签。

使用步骤:

  • 找到 select 元素
  • 实例化 Select 对象
import time
from selenium.webdriver.support.select import Select
from selenium import webdriver

driver = Chrome('./chromedriver')

# 控制浏览器访问url地址
driver.get('file:///home/python/code/unit_testing/selenium_code/test.html')

# 单选 select
el = driver.find_element_by_id('select-single')
select_single = Select(el)
options=select_single.options
for i in range(len(options)):
    # 通过下标选中
    select_single.select_by_index(i)
    time.sleep(1)

# 多选 select
el = driver.find_element_by_id('select-multiple')

select = Select(el)
options=select.options

print(options)
# 全部不选中
select.deselect_all()

for i in range(len(options)):
    # 通过下标选中
    select.select_by_index(i)
    time.sleep(1)

select.deselect_all()
View Code

2.7.2、常用属性和方法

select.options # select 中所有 options
select.all_selected_options # 所有被选中的 option
select.first_selected_option # 第一个被选中的 option

select.select_by_value(value) #  通过 option 的值选中
select.select_by_index(index) # 通过 option 的下标选中
select.select_by_visible_text(text) # 通过 option 的可见文本选中
select.deselect_all() # 全部不选中
select.deselect_by_value(value) # 通过 option 的值取消选中
select.deselect_by_index(index) # 通过 option 的下标取消选中
select.deselect_by_visible_text(text) # 通过 option 的文本取消选中
View Code

2.8、无界面模式

2.8.1、Selenium无界面模式

绝大多数服务器是没有界面的,selenium控制谷歌浏览器也是存在无界面模式的,这一小节我们就来学习如何开启无界面模式(又称之为无头模式)

开启无界面模式的方法

  • 实例化配置对象
    • options = webdriver.ChromeOptions()
  • 配置对象添加开启无界面模式的命令
    • options.add_argument("--headless")
  • 配置对象添加禁用gpu的命令
    • options.add_argument("--disable-gpu")
  • 实例化带有配置对象的driver对象
    • driver = webdriver.Chrome('./chromedriver', options=options)

    注意:macos中chrome浏览器59+版本,Linux中57+版本才能使用无界面模式!

     from selenium import webdriver
    
    options = webdriver.ChromeOptions() # 创建一个配置对象
    options.add_argument("--headless") # 开启无界面模式
    options.add_argument("--disable-gpu") # 禁用gpu
    driver = webdriver.Chrome('./chromedriver', options=options) # 实例化带有配置的driver对象
    
    driver.get('https://www.itcast.cn')
    print(driver.title)
    
    driver.quit()
    View Code

    2.9、综合练习

    使用selenium+unittest对美多v5.0项目(http://mp-meiduo-python.itheima.net)的登陆登出功能进行自动化测试,并生成测试报告

    2.9.1、目录结构

    image

    2.9.2、测试用例

    import unittest
    from selenium.webdriver import Chrome
    from parameterized import parameterized
    import time
    
    TIME = 0.3
    
    
    class TestUser(unittest.TestCase):
    
        def setUp(self) -> None:
            print('前置:创建Chrome对象')
            self.driver = Chrome('./drivers/chromedriver')
            self.driver.maximize_window()  # 最大化
            self.driver.implicitly_wait(10)  # 指定隐式等待的时间
    
        def tearDown(self) -> None:
            print('后置:退出driver')
            self.driver.quit()
    
        @parameterized.expand([('admin', 'admin'), ('mike', '1111111'), ('itcast', 'admin')])
        def test_uesrs(self, username, pwd):
            print('测试用例,selenium操作')
            # 1. 打开网址
            self.driver.get('http://mp-meiduo-python.itheima.net/')
    
            # 2. 定位元素,元素操作(点击、输入)
            # 找到主页面登陆连接按钮,点击
            self.driver.find_element_by_link_text('登录').click()
    
            # 找用户名输入框,清空内容,输入用户名
            el = self.driver.find_element_by_name('username')
            el.clear()
            time.sleep(TIME)
            el.send_keys(username)
            time.sleep(TIME)
    
            # 找密码输入框,清空内容,输入用户名
            el = self.driver.find_element_by_name('pwd')
            el.clear()
            time.sleep(TIME)
            el.send_keys(pwd)
            time.sleep(TIME)
    
            # 找复选框
            el = self.driver.find_element_by_name('remembered')
            # el.is_selected() # 这个元素是否被选中,如果选中了,返回True, 否则,返回False
            print(el.is_selected())
    
            if el.is_selected():  # 如果复选框是被选中的
                el.click()  # 再点击一下,复选框由选中变成没有选中的状态
    
            # 3. 登陆操作
            # 找到登陆按钮,点击,如果用户名、秘密正确,切换到登陆后的页面
            self.driver.find_element_by_class_name('input_submit').click()
            time.sleep(TIME)
    
            # 4. 登陆操作的结果,断言
            # 登陆时,网址为:http://mp-meiduo-python.itheima.net/login/
            # 登陆成功后,网址切换为http://mp-meiduo-python.itheima.net/
            # 作了登陆操作后,只要当前网址为http://mp-meiduo-python.itheima.net/,说明登陆成功
            self.assertEqual(self.driver.current_url,
                             'http://mp-meiduo-python.itheima.net/',
                             '登陆失败')
    
            # 登出
            # 1. 登陆成功后,才能登出
            # 2. 找登出按钮,点击
            self.driver.find_element_by_class_name('quit').click()
            # 3. 找成功退出后的变化规律
            #   http://mp-meiduo-python.itheima.net/ 变为 http://mp-meiduo-python.itheima.net/login/
    
            self.assertEqual(self.driver.current_url,
                             'http://mp-meiduo-python.itheima.net/login/',
                             '登出失败')
            time.sleep(TIME)
    View Code

    2.9.3、main.py

    import unittest
    from BeautifulReport import BeautifulReport
    
    if __name__ == '__main__':
        # 1. 创建suite测试套件(容器),把当前目录下的test文件加入到容器
        suite = unittest.defaultTestLoader.discover('./')
    
        # 2. 根据suite创建runner
        runner = BeautifulReport(suite)
    
        # 3. runner启动测试报告
        runner.report('美多登陆登出测试', '测试报告名字.html', './reports')
    View Code

    posted on 2020-10-22 16:24  yycnblog  阅读(1177)  评论(0)    收藏  举报

    导航