提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、环境准备
  • 二、webdriver
    • 操作浏览器的基本方法
    • 元素定位
      • xpath定位
      • css定位
    • 操作元素(键盘和鼠标事件)
      • 简单操作
      • submit 提交表单
      • 键盘操作
      • 鼠标悬停事件
      • 多窗口、句柄(handle)
        • 获取窗口句柄
        • 句柄切换
      • iframe
        • frame 和 iframe 区别
        • 163 登录界面
        • 切换iframe
      • select 下拉框
        • 认识 select
        • 二次定位
        • 直接定位
        • 其他定位方式
      • 弹窗操作
        • alert\confirm\prompt
        • alert 操作
        • confirm 操作
        • prompt 操作
      • 单选框和复选框
        • 单选框
        • 复选框:checkbox
      • table 定位
        • xpath 定位 table
        • 富文本练习
      • 获取页面元素
      • 爬取网页源码
        • page_source
        • re 非贪婪模式
      • cookie相关
        • 获取 cookies:get_cookies()
        • 登录后的 cookies
        • 获取登陆的cookie
        • 使用cookie绕过验证码登陆
  • 三、使用JavaScript
    • 控制滚动条
      • 通过标尺拖动滚动条
      • 通过元素拖动滚动条
    • 日历控件readonly
    • 内嵌滚动条
    • 元素属性修改
  • 四、浏览器打开python帮助文档
  • 五、Unittest
    • 案列1
      • expected_condtions
      • 断言方法
    • 案例2
    • 案例三
      • 创建项目
      • 被测对象
      • 测试用例
      • unittest进阶使用
  • 二次封装
    • 元素定位参数化(find_element)
    • 登陆方法参数化
      • 不会生成html报告原因
    • 异常处理(NoSuchElementException)
    • Excel处理
    • 补充知识,使用openpyxl库处理excel
      • 案例一、
      • 案例二、
      • 案例三、
      • 案例四、
      • 案例五、
      • 案例六、
      • 案例七、
      • 案例八、

前言

提示:学完本篇文章,自动化测试算是入门了


提示:以下是本篇文章正文内容,下面案例可供参考

一、环境准备

1、python3.7
2、pycharm
3、selenium
4、xpath与chrome控件

selenium下载
cmd窗口下输入:pip install selenium
版本问题可能导致安装失败

xpath控件在Google应用商店下载

chrome控件放入python安装的根目录

下载地址:http://chromedriver.storage.googleapis.com/index.html
请与chrome浏览器的版本相对应,否则无法启动

二、webdriver

操作浏览器的基本方法

元素定位


xpath定位






xpath模糊匹配

css定位

操作元素(键盘和鼠标事件)

简单操作

1.点击(鼠标左键)页面按钮:click()
2.请空输入框:clear()
3.输入字符串:send_keys()
4.截屏保存
driver.get_screenshot_as_file(u"C:\Users\Administrator\Desktop\123456\%s.png" % datetime.now().strftime("%Y%m%d.%H%M%S.%f")[:-3])

submit 提交表单

1.在前面百度搜索案例中,输入关键字后,可以直接按回车键搜索,也可以点搜索按钮
搜索。
2.submit()一般用于模拟回车键

键盘操作

1.selenium 提供了一整套的模拟键盘操作事件,前面 submit()方法如果不行的话,可以试试模拟键盘事件
2.模拟键盘的操作需要先导入键盘模块:from selenium.webdriver.common.keys import Keys
3.模拟 enter 键,可以用 send_keys(Keys.ENTER)

4.其它常见的键盘操作:
键盘 F1 到 F12:send_keys(Keys.F1) 把 F1 改成对应的快捷键
复制 Ctrl+C:send_keys(Keys.CONTROL,‘c’)
粘贴 Ctrl+V:send_keys(Keys.CONTROL,‘v’)
全选 Ctrl+A:send_keys(Keys.CONTROL,‘a’)
剪切 Ctrl+X:send_keys(Keys.CONTROL,‘x’)
制表键 Tab: send_keys(Keys.TAB)

鼠标悬停事件

1.鼠标不仅仅可以点击(click),鼠标还有其它的操作,如:鼠标悬停在某个元素上,鼠标右击,鼠标按住某个按钮拖动
2.鼠标事件需要先导入模块:from selenium.webdriver.common.action_chains import ActionChains
perform() 执行所有 ActionChains 中的行为
move_to_element() 鼠标悬停


右击鼠标:context_click()
双击鼠标:double_click()

多窗口、句柄(handle)

有些页面的链接打开后,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口了。获取窗口的唯一标识用句柄表示,所以只需要切换句柄,我们就能在多个页面上灵活自如的操作了。
本篇以打开百度新闻页面搜索按钮上的链接页面为例,依次打开每个按钮,并检验测试结果。用脚本批量操作,可以减少重复劳动,重复的事情让脚本去执行吧!

获取窗口句柄

1.打开百度新闻页面:17http://news.baidu.com/17
3.当点击百度新闻页面上新闻时,会打开一个新的窗口
3.人为操作的话,可以通过点击窗口切换到不同的窗口上,但是脚本它不
知道你要操作哪个窗口,这时候只能获取窗口唯一的标识:句柄
4.获取当前页面的句柄:driver.current_window_handle
5.获取所有窗口的句柄:driver.window_handles

句柄切换

iframe

有很多小伙伴在拿 163 作为登录案例的时候,发现不管怎么定位都无法定位到,到底是什么鬼呢,下面详细介绍 iframe 相关的切换

frame 和 iframe 区别

frame 与 iframe 两者可以实现的功能基本相同,不过 iframe 比 frame 具有更多的灵活性。 frame 是整个页面的框架,iframe 是内嵌的网页元素,也可以说是内嵌的框架

iframe 标记又叫浮动帧标记,可以用它将一个 HTML 文档嵌入在一个 HTML中显示。它和 Frame 标记的最大区别是在网页中嵌入 的所包含的内容与整个页面是一个整体,而< /frame>所包含的内容是一个独立的个体,是可以独立显示的。另外,应用 iframe 还可以在同一个页面中多次显示同一内容,而不必重复这段内容的代码。

163 登录界面

确认登陆在iframe框架下

切换iframe

iframe 的切换是默认支持 id 和 name 的方法的

select 下拉框

认识 select

1.打开百度-设置-高级搜索设置界面,如下图所示

二次定位

界面改版,提供老版本百度下拉框定位方式,主要是为了了解流程,现版本不可用

选项有三个

每页显示 10 条 每页显示 20 条 每页显示 50 条

直接定位

可直接用

其他定位方式

这里只提供方法

弹窗操作

不是所有的弹出框都叫 alert,在使用 alert 方法前,先要识别出到底是不是alert。先认清楚 alert 长什么样子,下次碰到了,就可以用对应方法解决。
alert\confirm\prompt 弹出框操作主要方法有:
text:获取文本值
accept() :点击"确认"
dismiss() :点击"取消"或者叉掉对话框
send_keys() :输入文本值 --仅限prompt,在 alert 和 confirm 上没有输入框

alert\confirm\prompt

html代码如下,复制下面代码,改为html后缀的文件

<html>
<head>
<title>Alert</title>
</head>
<body>
<input id = "alert" value = "alert" type = "button" onclick = "alert('您关注了 ht 吗?');"/>
<input id = "confirm" value = "confirm" type = "button" onclick ="confirm('确定关注微信公众号:ht?');"/>
<input id = "prompt" value = "prompt" type = "button" onclick = "var name= prompt('请输入微信公众号:','ht'); document.write(name)"/>
</body>
</html>



alert 操作

1.先用 switch_to.alert()方法切换到 alert 弹出框上
2.可以用 text 方法获取弹出的文本 信息
3.accept()点击确认按钮
4.dismiss()相当于点右上角 x,取消弹出框
(url 的路径,直接复制浏览器打开的路径)
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
url = "C:\\Users\\Administrator\\Desktop\\122.html"
driver.get(url)
sleep(2)
driver.find_element_by_id("alert").click()  #点击”alert按钮“
sleep(2)
t = driver.switch_to.alert  #切换到alert弹出框
print(t.text)
t.accept()  #点击弹出框确认按钮
driver.find_element_by_id("alert").click()
sleep(2)
t = driver.switch_to.alert
t.dismiss()  #退出弹出框

confirm 操作

1.先用 switch_to_alert()方法切换到 alert 弹出框上
2.可以用 text 方法获取弹出的文本 信息
3.accept()点击确认按钮
4.dismiss()相当于点取消按钮或点右上角 x,取消弹出框
(url 的路径,直接复制浏览器打开的路径)
driver = webdriver.Chrome()
url = "C:\\Users\\Administrator\\Desktop\\122.html"
driver.get(url)
sleep(2)
driver.find_element_by_id("confirm").click()  #点击”confirm"按钮
sleep(2)
t = driver.switch_to.alert  #切换到alert弹出框
print(t.text)
t.accept()  #点击弹出框确认按钮
driver.find_element_by_id("alert").click()
sleep(2)
t = driver.switch_to.alert
t.dismiss()  #退出弹出框,相当于取消按钮

prompt 操作

1.先用 switch_to_alert()方法切换到 alert 弹出框上
2.可以用 text 方法获取弹出的文本 信息
3.accept()点击确认按钮
4.dismiss()相当于点右上角 x,取消弹出框
5.send_keys()这里多个输入框,可以用 send_keys()方法输入文本内容
(url 的路径,直接复制浏览器打开的路径)
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
url = "C:\\Users\\Administrator\\Desktop\\122.html"
driver.get(url)
sleep(2)
driver.find_element_by_id("prompt").click()  #点击”confirm"按钮
sleep(2)
t = driver.switch_to.alert  #切换到alert弹出框
print(t.text)
t.send_keys("hello word")   #输入文本信息
sleep(2)
t.accept()  #点击弹出框确认按钮
#t.dismiss()  #退出弹出框,相当于取消按钮

单选框和复选框

HTML源码

<html>
<head>
<meta http-equiv="content-type"
content="text/html;charset=utf-8" />
<title>单选和复选</title>
</head>
<body>
</form>
<h4>单选:性别</h4>
<form>
<label value="radio"></label>
<input name="sex" value="male" id="boy" type="radio"><br>
<label value="radio1"></label>
<input name="sex" value="female" id="girl" type="radio">
</form>
<h4>微信公众号:selenium高级自动化编程</h4>
<form>
<!-- <label for="c1">checkbox1</label> -->
<input id="c1" type="checkbox">selenium<br>
<!-- <label for="c2">checkbox2</label> -->
<input id="c2" type="checkbox">python<br>
<!-- <label for="c3">checkbox3</label> -->
<input id="c3" type="checkbox">appium<br>
<!-- <form>
<input type="radio" name="sex" value="male" /> Male
<br />
<input type="radio" name="sex" value="female" /> Female
</form> -->
</body>
</html>

单选框

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
url = "C:\\Users\\Administrator\\Desktop\\233.html"
driver.get(url)
a = driver.find_element_by_id("boy").is_selected()    #判断是否被选择
b = driver.find_element_by_id("girl").is_selected()
print("boy是否选中:",a)
print("girl是否选中:",b)
driver.find_element_by_id("boy").click()   #点击单选
a1 = driver.find_element_by_id("boy").is_selected()
b1 = driver.find_element_by_id("girl").is_selected()
print("boy是否选中:",a1)
print("girl是否选中:",b1)
sleep(2)
driver.find_element_by_id("girl").click()  #点击单选

复选框:checkbox

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
url = "C:\\Users\\Administrator\\Desktop\\233.html"
driver.get(url)
a = driver.find_element_by_id("c1").is_selected()    #判断是否被选择
b = driver.find_element_by_id("c2").is_selected()
print("selenium是否选中:",a)
print("python是否选中:",b)
driver.find_element_by_id("c1").click()   #点击单选
sleep(2)
a1 = driver.find_element_by_id("c1").is_selected()
b1 = driver.find_element_by_id("c2").is_selected()
print("selenium是否选中:",a1)
print("python是否选中:",b1)
driver.find_element_by_id("c1").click()   #点击单选
driver.find_element_by_id("c2").click()   #点击单选
driver.find_element_by_id("c3").click()   #点击单选
sleep(2)
a11 = driver.find_element_by_id("c1").is_selected()
b11 = driver.find_element_by_id("c2").is_selected()
print("selenium是否选中:",a11)
print("python是否选中:",b11)
from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
url = "C:\\Users\\Administrator\\Desktop\\233.html"
driver.get(url)
#find_elements_by_xpath与find_element_by_xpath
checkbox = driver.find_elements_by_xpath("//*[@type='checkbox']")
#全部勾选
for i in checkbox:i.click()

table 定位

源码

<!DOCTYPE html>
<meta charset="UTF-8"> <!-- for HTML5 -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<html><head><title>Table 测试模板</title></head><body><table border="1" id="myTable"><tr><th>QQ 群</th><th>QQ 号</th><th>群主</th></tr><tr><td>selenium高级自动化编程</td> <td>123456</td><td>ht</td></tr><tr><td>appium 自动化</td><td>123456789</td><td>ht</td></tr></table></body>
</html>


table特征:

1.table 页面查看源码一般有这几个明显的标签:table、tr、th、td
2.<table>标示一个表格
3.<tr>标示这个表格中间的一个行
4.</th> 定义表头单元格
5.</td> 定义单元格标签,一组<td>标签将建立一个单元格,<td>标签必须放在<tr>标签内

xpath 定位 table

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
url = "C:\\Users\\Administrator\\Desktop\\222.html"
driver.get(url)
#定位selenium高级自动化编程  /tbody/必须加
t = driver.find_element_by_xpath("//table[@id='myTable']/tbody/tr[2]/td[1]")
print(t.text)

富文本练习

最后写入图片的时候错误,暂时没找到原因

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
from selenium.webdriver.common.keys import Keysurl = "https://www.cnblogs.com/"
driver.get(url)
driver.maximize_window()
sleep(2)#登陆
driver.find_element_by_xpath("//*[@id='navbar_login_status']/a[4]").click()
driver.find_element_by_id("mat-input-0").send_keys("192@qq.com")
driver.find_element_by_id("mat-input-1").send_keys("ht5")
driver.find_element_by_id("mat-input-1").send_keys(Keys.ENTER)
sleep(10)#进入文本编辑器
#//*[@id="myblog_icon"]
driver.find_element_by_xpath("//*[@id='myblog_icon']").click()
sleep(3)
driver.find_element_by_xpath("//*[@id='blog_nav_newpost']").click()
sleep(2)#标题输入
driver.find_element_by_id("post-title").send_keys("测试")
sleep(2)#正文输入
driver.switch_to.frame("Editor_Edit_EditorBody_ifr")
driver.find_element_by_id("tinymce").send_keys("测试成功")
driver.switch_to.default_content()
sleep(2)
#图片上传
driver.find_element_by_id("Editor_Edit_EditorBody_uploadImage").click()
sleep(4)
#<iframe id="mce_80_ifr" frameborder="0" >iframe为动态
iframe = driver.find_elements_by_tag_name("iframe")  #获取所有的frame
iframe = driver.find_elements_by_tag_name("iframe")[1]
driver.switch_to_frame(iframe)
driver.find_element_by_name('file').send_keys(r"C:\\Users\\Administrator\\Desktop\\home\\pill\\img\\bg1.png")print(len(iframe))# driver.switch_to.frame(iframe)
# sleep(2)
#driver.find_element_by_xpath("//*[@id='jquery-wrapped-fine-uploader']/div/div/input").send_keys(r"C:\\Users\\Administrator\\Desktop\\home\\pill\\img\\bg1.png")
#driver.find_element_by_name("file").send_keys(r"C:\\Users\\Administrator\\Desktop\\home\\pill\\img\\bg1.png")
#driver.find_element_by_xpath("//*[@id='jquery-wrapped-fine-uploader']/div/div/input").click()
#driver.find_element_by_name('file').click()

获取页面元素

通常在做断言之前,都要先获取界面上元素的属性,然后与期望结果对比

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
sleep(2)
#获取页面标题
title = driver.title
print("网页标题:",title)
#获取元素的文本
text = driver.find_element_by_xpath("//*[@id='bottom_layer']/div[1]/p[1]/a").text
print("元素文本:",text)
#获取元素的标签
tag = driver.find_element_by_id("kw").tag_name
print("百度输入框元素标签:",tag)
#获取其它属性方法:get_attribute("属性"),这里的参数可以是 class、name 等任意属性
classname = driver.find_element_by_id("kw").get_attribute("class")
print("百度输入框的class属性:",classname)
#获取输入框内的文本值
driver.find_element_by_id("kw").send_keys("input的文本值")
value = driver.find_element_by_id("kw").get_attribute("value")
print("已经输入的文本值:",value)
#获取浏览器名称
browser = driver.name
print("浏览器标识符:",browser)

爬取网页源码

有时候通过元素的属性的查找页面上的某个元素,可能不太好找,这时候可以从源码中爬出想要的信息。selenium 的page_source 方法可以获取到页面源码。

page_source

selenium的page_source可以直接返回网页源码

#coding:utf-8
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
page = driver.page_source
print(page)

re 非贪婪模式

#coding:utf-8
from selenium import webdriver
import re   #正则表达式,非贪婪模式启动
driver = webdriver.Chrome()
driver.get("https://blog.csdn.net/weixin_44487337")
page = driver.page_source
#findall返回的是一个列表,同时过滤非href  不同的去学习一下正则表达式
url_list = re.findall('href=\"(.*?)\"',page,re.S)
url_all = []  #定义一个空的列表
for url in url_list:if "http" in url:print(url)url_all.append(url)  #列表写入
print(url_all)

cookie相关

虽然 cookie 相关操作在平常 ui 自动化中用得少,偶尔也会用到,比如登录有图形验证码,可以通过绕过验证码方式,添加 cookie 方法登录。
登录后换账号登录时候,也可作为后置条件去删除 cookie 然后下个账号登录

获取 cookies:get_cookies()

1.获取 cookies 方法直接用:get_cookies()
2.先启动浏览器,获取 cookies,打印出来发现是空:[]
3.打开博客首页后,重新获取 cookies,打印出来,就有值了

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
from selenium.webdriver.common.keys import Keys
cokkie_3 =driver.get_cookies()
print(cokkie_3)
url = "https://www.cnblogs.com/"
driver.get(url)
driver.maximize_window()
sleep(2)
cokkie_1 =driver.get_cookies()
print(cokkie_1)

登录后的 cookies

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
from selenium.webdriver.common.keys import Keys
cokkie_3 =driver.get_cookies()
print(cokkie_3)
url = "https://www.cnblogs.com/"
driver.get(url)
driver.maximize_window()
sleep(2)
cokkie_1 =driver.get_cookies()
print(cokkie_1)#登陆
driver.find_element_by_xpath("//*[@id='navbar_login_status']/a[4]").click()
driver.find_element_by_id("mat-input-0").send_keys("******")
driver.find_element_by_id("mat-input-1").send_keys("******")
driver.find_element_by_id("mat-input-1").send_keys(Keys.ENTER)
sleep(10)
cokkie_2 =driver.get_cookies()
print(cokkie_2)

如下图,name与value发生变化

获取登陆的cookie

1.get_cookies(): 获 取 所 有 cookies 2.driver.get_cookie(name):获取指定 name 的 cookie:
3. 清 除 指 定 cookie:delete_cookie() 4.delete_all_cookies():清除所有 cookies
5.add_cookie(cookie_dict):添加 cookie 的值

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
from selenium.webdriver.common.keys import Keys
url = "https://www.cnblogs.com/"
driver.get(url)
driver.maximize_window()
sleep(2)
#登陆
driver.find_element_by_xpath("//*[@id='navbar_login_status']/a[4]").click()
driver.find_element_by_id("mat-input-0").send_keys("*****")
driver.find_element_by_id("mat-input-1").send_keys("*****")
driver.find_element_by_id("mat-input-1").send_keys(Keys.ENTER)
sleep(10)
cookie_1 = driver.get_cookie(name=".Cnblogs.AspNetCore.Cookies") #获取登陆的cookie
print(cookie_1)
cookie_2 = driver.get_cookies()  #获取所有的cookie
print(cookie_2)
driver.delete_cookie(name=".Cnblogs.AspNetCore.Cookies")  #删除登陆的cookie
# driver.delete_all_cookies() #清除所有的cookie
sleep(8)
driver.refresh()  #刷新界面,用户已经退出,证明.Cnblogs.AspNetCore.Cookies是登陆的cookie的一部分

使用cookie绕过验证码登陆

.get_cookies()获取到的cookie与浏览器F12获取的如下图,一模一样

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
from selenium.webdriver.common.keys import Keys
url = "https://www.cnblogs.com/"
driver.get(url)
driver.maximize_window()
sleep(2)
#添加cookie
u1 = {"domain":"cnblogs.com","name":"CNBlogsCookie","value":"23D8B5601F6AB78B3E87252F6B9CE00C0956B74C85DF818407C639E5410A57BD25B79BEDE403F8EC22EF61CA4F0CA5C419A93AABF4F7C1036F20E36C9B2524591E53C2671CC18B2FFC5556B8BFEEF0D264C0EB43"}
u2 = {"domain":"cnblogs.com","name":".Cnblogs.AspNetCore.Cookies","value":"CfDJ8AHUmC2ZwXVKl7whpe9_lavnfct879j1VAOlH63-UUvF8AmiipR8olNqV5q_DUtgfSwtV8RbB38VyJkoYckyrIpLrjEp-YXrwt63w9LhT5Mx-后面太长我就不粘贴了"}
driver.add_cookie(u1)
driver.add_cookie(u2)
sleep(5)
driver.refresh() #这里刷新后发现用户已登录,亲测有效

三、使用JavaScript

有些特殊的操作 selenium2+python 无法直接完成的,JS 刚好是这方面的强项
链接: http://www.w3school.com.cn/js/index.asp4

控制滚动条

通过标尺拖动滚动条

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.bilibili.com/")
driver.set_window_size(500,800)
sleep(3)
driver.execute_script("window.scrollTo(200,400)")

通过元素拖动滚动条

from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.52pojie.cn/")
target = driver.find_element_by_xpath("//*[@id='ct']/div[3]/div[3]/div[3]/div[1]/h2/a")
driver.execute_script("arguments[0].scrollIntoView();", target)

日历控件readonly

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.12306.cn/")
sleep(2)
"""
<input type="text" class="input inp-txt_select" value="2018-07-21" id="train_date" readonly>
"""
#去掉元素readonly属性
js = 'document.getElementById("train_date").removeAttribute("readonly");'
driver.execute_script(js)
sleep(3)
#用JS方法输入日期
js_value= 'document.getElementById("train_date").value="2020-12-07"'
driver.execute_script(js_value)
#清空后重新输入
sleep(3)
driver.find_element_by_id("train_date").clear()
driver.find_element_by_id("train_date").send_keys("2020-12-09")

内嵌滚动条

页面源码

<!DOCTYPE html>
<meta charset="UTF-8"> <!-- for HTML5 -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<html> <head> <style type="text/css">div.scroll {background-color:#afafaf; width:500px;  height:100px; overflow:auto; }</style> </head> <body> <p>测试滚动条</p> <p>这是一个内嵌的div滚动条</p> <div id="kw" name="kww" class="scroll">这是一个内嵌 div:物联网平台支持为产品定义物模型,将实际产品抽象成由属性、服务、事件所组成的数据模型,便于云端管理和数据交互。产品创建完成后,您可以为它定义物模型,产品下的设备将自动继承物模型内容。草稿发布之后会变为正式版本,发布一次就新增一次版本!!功能定义又分为两个页签,标准功能和自定义功能。下面列出了设备厂商接入时的常见问题,强烈建议设备厂商将这些问题浏览一遍以加深对阿里云IoT物联网。平台以及Link SDK的了解。 使用具体编程语言SDK时碰到的问题,请参考相应语言zhegedancihenchanghenchangchangchangchangchanchanchanchangchangchangchancg</div> </body>
</html>

拖动操作

#encoding:utf-8
from selenium import webdriver
from time import sleep
driver=webdriver.Chrome()
driver.get('file:///C://Users//Administrator//Desktop//hh.html')
sleep(2)# 竖向滚动条操作
js1='var q=document.getElementById("kw").scrollTop = 10000'
driver.execute_script(js1)
sleep(2)
js2='var q=document.getElementById("kw").scrollTop = 0'
driver.execute_script(js2)
sleep(2)# 横向滚动条操作
js3='var q=document.getElementById("kw").scrollLeft = 10000'
driver.execute_script(js3)
sleep(2)
js4='var q=document.getElementById("kw").scrollLeft = 0'
driver.execute_script(js4)
sleep(2)# 用classname
js5 = "var q=document.getElementsByClassName('scroll')[0].scrollTop = 10000"
driver.execute_script(js5)
sleep(2)
js6 = "var q=document.getElementsByClassName('scroll')[0].scrollLeft = 10000"
driver.execute_script(js6)

元素属性修改

JS处理多窗口,在自动化过程中多窗口情况处理往往很麻烦,可以通过修改target属性来防止多窗口情况发生

from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.maximize_window()
sleep(3)
#登陆
driver.find_element_by_xpath("//*[@id='u1']/a").click()
sleep(5)
driver.find_element_by_xpath("//*[@id='TANGRAM__PSP_11__footerULoginBtn']").click()
sleep(2)
driver.find_element_by_id("TANGRAM__PSP_11__userName").send_keys("******")
sleep(1)
driver.find_element_by_id("TANGRAM__PSP_11__password").send_keys("******")
sleep(1)
driver.find_element_by_id("TANGRAM__PSP_11__submit").click()
sleep(5)
#删除元素属性
js='document.getElementById("s-top-username").removeAttribute("target")'
driver.execute_script(js)
#这里不会创建新的窗口
driver.find_element_by_xpath("//*[@id='s-top-username']/span[2]").click()
#给id为s-top-username的元素 增加 title属性并赋值为“测试title”
js='document.getElementById("s-top-username").setAttribute("title","测试title")'
#给id为s-top-username的元素 删除 title属性
js='document.getElementById("s-top-username").removeAttribute("title")'
#获取id为s-top-username的元素 title属性的值
js='document.getElementById("s-top-username").getAttribute("title")'
#修改id为s-top-username的元素 title属性的值
js='document.getELementById("s-top-username").title="测试"'
注意:
getELementBy***
例:
getELementByClassName
getELementByName

四、浏览器打开python帮助文档

打开cmd窗口,输入python -m pydoc -p 10000

浏览器输入网址:http://localhost:10000/

五、Unittest

python 的单元测试框架,是基于 java 的 junit 测试框架。

案列1

# encoding = utf-8
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
import unittest
class Blog(unittest.TestCase):def setUp(self):self.driver = webdriver.Chrome()self.driver.get("https://www.cnblogs.com/htxz/")#测试用例的名称要以 test 开头def test_blog(self):sleep(3)#判断当前页面的title是否完全等于预期字符串,返回布尔值result = EC.title_is("会走路的桃子 - 博客园")(self.driver)# 打印出True还是 Falseprint(result)#测试该表达式是真值self.assertTrue(result)def tearDown(self):self.driver.quit()
if __name__ == "__main__":unittest.main()

expected_condtions

16种判断页面元素的方法

from selenium.webdriver.support import expected_conditions
expected_condtions提供了16种判断页面元素的方法:1.title_is:判断当前页面的title是否完全等于预期字符串,返回布尔值2.title_contains:判断当前页面的title是否包含预期字符串,返回布尔值3.presence_of_element_located:判断某个元素是否被加到dom树下,不代表该元素一定可见4.visibility_of_element_located:判断某个元素是否可见,可见代表元素非隐藏,并且元素的宽和高都不为05.visibility_of:跟上面的方法是一样的,只是上面需要传入locator,这个方法直接传定位到的element就好6.presence_of_all_elements_located:判断是否至少一个元素存在于dom树中,举个例子,如果页面上有n个元素的class都是'coumn-md-3',name只要有一个元素存在,这个方法就返回True7.text_to_be_present_in_element:判断某个元素中的text文本是否包含预期字符串8.text_to_be_present_in_element_value:判断某个元素中的value属性值是否包含了预期字符串9.frame_to_be_availabe_and_switch_to_it:判断该frame是否可以switch进去,如果可以,则返回True并且switch进去,否则返回False10.invisibility_of_element_located:判断某个元素是否不存在于dom树或不可见11.element_to_be_clickable:判断某个元素是见并且是enable(有效),这样的话才叫clickable12.staleness_of:等某个元素从dom树下移除,返回TrueFalse13.element_to_be_selected:判断某个元素是否被选中,一般用于select下拉表14.element_selection_state_to_be:判断某个元素的选中状态是否符合预期15.element_located_selection_state_to_be:跟上面的方法一样,只是上面的方法传入定位到的element,这个方法传入locator16.alert_is_present:判断页面上是会否存在alert

断言方法

方法 描述
assertEqual(arg1, arg2, msg=None) 验证arg1=arg2,不等则fail
assertNotEqual(arg1, arg2, msg=None) 验证arg1 != arg2, 相等则fail
assertTrue(expr, msg=None) 验证expr是true,如果为false,则fail
assertFalse(expr,msg=None) 验证expr是false,如果为true,则fail
assertIs(arg1, arg2, msg=None) 验证arg1、arg2是同一个对象,不是则fail
assertIsNot(arg1, arg2, msg=None) 验证arg1、arg2不是同一个对象,是则fail
assertIsNone(expr, msg=None) 验证expr是None,不是则fail
assertIsNotNone(expr, msg=None) 验证expr不是None,是则fail
assertIn(arg1, arg2, msg=None) 验证arg1是arg2的子串,不是则fail
assertNotIn(arg1, arg2, msg=None) 验证arg1不是arg2的子串,是则fail
assertIsInstance(obj, cls, msg=None) 验证obj是cls的实例,不是则fail
assertNotIsInstance(obj, cls, msg=None) 验证obj不是cls的实例,是则fail

案例2

from selenium import webdriver
from time import sleep
#导入键盘操作模块
from selenium.webdriver.common.keys import Keys
import unittest
class Blog(unittest.TestCase):#登陆网站def setUp(self):self.driver = webdriver.Chrome()self.driver.get("https://www.cnblogs.com/")#参数化登陆账号密码def login(self,username,psw):self.driver.find_element_by_xpath("//*[@id='navbar_login_status']/a[4]").click()self.driver.find_element_by_id("mat-input-0").send_keys(username)self.driver.find_element_by_id("mat-input-1").send_keys(psw)self.driver.find_element_by_id("mat-input-1").send_keys(Keys.ENTER)sleep(15)#验证登陆是否成功,找一个登陆后才有的元素,这里我随便写的def is_login_sucess(self):try:text = self.driver.find_element_by_id("myblog_icon").textprint(text)return Trueexcept:return False#用例部分def test_login_1(self):self.login("1923501505@qq.com","******")result = self.is_login_sucess()self.assertTrue(result)def test_login_2(self):self.login("1923501505@qq.com","******")result = self.is_login_sucess()self.assertTrue(result)def test_login_3(self):self.login("1923501505@qq.com","******")result = self.is_login_sucess()self.assertTrue(result)#退出浏览器def setDown(self):self.driver.quit()
#执行
if __name__ == "__main__":unittest.main()

案例三

创建项目

创建一个项目,在该项目下创建以下几个py文件

被测对象:myClass.py
测试用例:Test_Myclass.py Test_Myclass2.py
运行用例:main.py main1.py main2.py

被测对象

#这里定义了一个类,用与计算加法与减法
class Math:def add(self, a, b):return a + bdef minus(self, a, b):return a - b

测试用例

import unittest
#调用被测对象
from myClass import Mathclass Test_MyClass(unittest.TestCase):#如果在setUp里实例化被测文件中的类,那么每一条测试用例都要实例化一次被测类,用setUpClass()#可以只实例化一次,同理,tearDownClass也只做一次收尾工作@classmethoddef setUpClass(cls):cls.m = Math()@classmethoddef tearDownClass(cls):pass# 被测文件中的类,注意测试用例是以test_开头#测试用例的执行顺序是以字母a-z和数字的从小到大的顺序来排列的,可以在test_后面加数字,控制运行顺序def test_2add(self):  #加法result = self.m.add(100, 23)print("我先执行")self.assertEqual(123, result)def test_1minus(self):  #减法result = self.m.minus(235, 111)print("我后执行")self.assertEqual(124, result)  #断言
#私有属性,可单独运行,其他py文件不可调用
if __name__ == "__main__":unittest.main()

unittest进阶使用

一)main.py

import unittest
from Test_Myclass import Test_MyClass  #调用Test_Myclass.py文件#实例化被测对象
s = unittest.TestSuite()#调用addTest来加载测试用例  addTest(类名("用例函数名称"))——添加一个测试用例
#方法1
s.addTest(Test_MyClass("test_2add"))
s.addTest(Test_MyClass("test_1minus"))
#方法2
s.addTests([Test_MyClass("test_2add"),Test_MyClass("test_1minus")])#使用TextTestRunner来运行测试用例
fs = open("test_run_result.txt","w") #打开一个文件
#实例化  输出测试报告到文件
#runner = unittest.TestRunner()
runner = unittest.TextTestRunner(fs)
#用run方法就是用来运行测试用例的
runner.run(s)

二)main1.py
unittest.TestLoader.discover方法匹配目录下的用例

import os
import unittest
#实例化测试套件对象
s = unittest.TestSuite()
#1.实例化TestLoader对象  2.使用discover去找到一个目录下的所有测试用例
loader = unittest.TestLoader()
#3.使用addTests将找到的测试用例放在测试套件下  4.os.getcwd()方法用于返回当前工作目录。
s.addTests(loader.discover(os.getcwd()))
#运行
runner = unittest.TextTestRunner()
runner.run(s)

三)main2.py
html报告

import unittest, os, time
from HTMLTestRunner import HTMLTestRunner#实例化测试套件对象
s = unittest.TestSuite()
#1.实例化TestLoader对象  2.使用discover去找到一个目录下的所有测试用例
loader = unittest.TestLoader()
#3.使用addTests将找到的测试用例放在测试套件下
s.addTests(loader.discover(os.getcwd()))#获取当前时间
curTime = time.strftime("%Y-%m-%d_%H-%M-%S")
#在当前目录下创建一个html文件
fp = open(os.getcwd() + "/autoTest_report_{0}.html".format(curTime), "wb")#运行测试用例,生成测试报告
runner = HTMLTestRunner(stream=fp,title="单元测试报告",description="Math类的单元测试报告"
)
runner.run(s)
# -*- coding: utf-8 -*-
from selenium import webdriver
from HTMLTestRunner import HTMLTestRunner
import unittest
import timeclass BaiduIdeTest(unittest.TestCase):def setUp(self):self.driver = webdriver.Chrome()self.driver.implicitly_wait(30)self.base_url = "https://www.baidu.com/"def test_baidu_ide(self):driver = self.driverdriver.get(self.base_url)driver.find_element_by_id("kw").clear()driver.find_element_by_id("kw").send_keys("HTMLTestRunner")driver.find_element_by_id("su").click()time.sleep(5)self.assertEqual(u"HTMLTestRunner_百度搜索", driver.title)def tearDown(self):self.driver.quit()if __name__ == "__main__":# 构造测试套件testsuit = unittest.TestSuite()testsuit.addTest(BaiduIdeTest("test_baidu_ide"))# 定义测试报告存放路径fp = open('./result1.html', 'wb')# 定义测试报告runner = HTMLTestRunner(stream=fp,title='自动化测试报告',description='用例执行情况:')runner.run(testsuit)# 关闭测试报告fp.close()

二次封装

元素定位参数化(find_element)

#encoding:utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element(By.ID,"kw").send_keys("python")
sleep(3)
driver.find_element(By.ID,"su").click()
sleep(3)
driver.quit()
#encoding:utf-8
from selenium import webdriver
#from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element("id","kw").send_keys("python")
sleep(3)
driver.find_element("id","su").click()
sleep(3)
driver.quit()# by_id= "id"
# by_xpath = "xpath"
# by_link_text = "link text"
# by_partial_text = "partial link text"
# by_name = "name"
# by_tag_name = "tag name"
# by_class_name = "class name"
# by_css_selector = "css selector"

登陆方法参数化

from selenium import webdriver
from time import sleep
from HTMLTestRunner import HTMLTestRunner
#导入键盘操作模块
from selenium.webdriver.common.keys import Keys
import unittest
class Blog(unittest.TestCase):#登陆网站def setUp(self):self.driver = webdriver.Chrome()self.driver.get("https://www.cnblogs.com/")#参数化登陆账号密码def login(self,username,psw):self.driver.find_element("xpath","//*[@id='navbar_login_status']/a[4]").click()self.driver.find_element("id","mat-input-0").send_keys(username)self.driver.find_element("id","mat-input-1").send_keys(psw)self.driver.find_element("id","mat-input-1").send_keys(Keys.ENTER)sleep(15)self.driver.find_element_by_xpath("//*[@id='myblog_icon']").click()#判断登陆是否成功def is_login_sucess(self):try:text = self.driver.find_element("id", "Header1_HeaderTitle").textprint(text)return Trueexcept:return False#用例部分def test_login_1(self):self.login("1923501505@qq.com","****")  #调用登陆方法result = self.is_login_sucess()  #判断结果self.assertTrue(result)# def test_login_2(self):#     self.login("1923501505@qq.com","****")#     result = self.is_login_sucess()#     self.assertTrue(result)# def test_login_3(self):#     self.login("1923501505@qq.com","****")#     result = self.is_login_sucess()#     self.assertTrue(result)#退出浏览器def setDown(self):self.driver.quit()
if __name__ == "__main__":# 构造测试套件suit = unittest.TestSuite()suit.addTest(Blog("test_login_1"))# 定义测试报告存放路径fp = open('./result7712.html', 'wb')# 定义测试报告runner = HTMLTestRunner(stream=fp,title='自动化测试报告',description='用例执行情况:')runner.run(suit)# 关闭测试报告fp.close()

不会生成html报告原因

PyCharm会默认使用自带的unittest框架来执行单元测试,不会执行main函数中的代码,所以不生成测试报告,所以你直接执行上面的代码会有问题
解决方案如下



异常处理(NoSuchElementException)

案例(一)

#encoding = utf-8
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
dr = webdriver.Chrome()
dr.get("https://www.baidu.com")
try:element = dr.find_element("id","s1u")
except NoSuchElementException as msg:print("查找元素异常:{}".format(msg))print("查找元素异常:%s"%msg)dr.quit()
else:element.click()dr.quit()

常见异常:
1.NoSuchElementException:没有找到元素

2.NoSuchFrameException:没有找到iframe

3.NoSuchWindowException:没找到窗口句柄handle

4.NoSuchAttributeException:属性错误

5.NoAlertPresentException:没找到alert弹出框

6.ElementNotVisibleException:元素不可见

7.ElementNotSelectableException:元素没有被选中

8.TimeoutException:查找元素超时

不导入异常模块 Exception

#encoding = utf-8
from selenium import webdriver
dr = webdriver.Chrome()
dr.get("https://www.baidu.com")
try:element = dr.find_element("id","s1u")
except Exception as msg:print("查找元素异常:{}".format(msg))print("查找元素异常:%s"%msg)dr.quit()
else:element.click()dr.quit()

Excel处理

当登录的账号有多个的时候,我们一般用 excel 存放测试数据,python 读取 excel 方法,并保存为字典格式。
准备:安装xlrd
pip install xlrd

import xlrd
# 打开 exlce 表格,参数是文件路径
data = xlrd.open_workbook("C:\\Users\\Administrator\\Desktop\\xlrd.1")#获取表单
#通过索引顺序获取
table = data.sheets()[0]
table = data.sheet_by_index(0)
#通过名称获取
table = data.sheet_by_name(u"Sheet1")#获取表单中的一些数据
# 获取总行数
nrows = table.nrows
# 获取总列数
ncols = table.ncols# 获取一行或一列的值,参数是第几行
table.row_values(0) # 获取第一行值
table.col_values(0) # 获取第一列值"""
在excel中存放数据,第一行为标题,也就是对应字典里面的key值,如:username,password
如果 excel 数据中有纯数字的一定要右键->设置单元格格式->文本格式,要不然读取的数据是浮点数
"""
#encoding:utf-8
import xlrd
class ExcelUtil():def __init__(self,excelPath,sheetName):self.data = xlrd.open_workbook(excelPath)self.table = self.data.sheet_by_name(sheetName)#获取第一行作为key值self.keys = self.table.row_values(0)#获取总行数self.rowNum = self.table.nrows#获取总列数self.colNum = self.table.ncolsdef dict_data(self):if self.rowNum <= 1:print("总行数小于一")else:r = []j = 1for i in range(self.rowNum-1)s = {}#从第二行开始取对应的value值values = self.table.row_values(j)for x in range(self.colNum)s[self.keys[x]] = values[x]r.append(s)j = j + 1return r
if __name__ == "__main__":filepath = "C:\\Users\\Administrator\\Desktop\\xlrd.1"sheetName = "Sheet1"data = ExcelUtil(filepath, sheetName)print(data.dict_data())

不对,这个xlrd库不好用

补充知识,使用openpyxl库处理excel

案例一、

import openpyxl
#创建excel工作薄
wb = openpyxl.Workbook()
#创建一个表单
wb.create_sheet("test_case")
#保存为xlsx的文件
wb.save("cases.xlsx")# 读取excel中的数据
# 第一步:打开工作簿
wb = openpyxl.load_workbook("cases.xlsx")
#第二步:选取表单
sh = wb["test_case"]
# 第三步:读取数据
# 参数 row:行  column:列
ce = sh.cell(row=1,column=1)
print(ce.value)print(list(sh.rows)[1:])     # 按行读取数据,去掉第一行的表头信息数据
#一行一行的遍历
for cases in list(sh.rows)[1:]:# 读取第一行,第一列的数据case_id =  cases[0].valuecase_excepted = cases[1].valuecase_data = cases[2].valueprint(case_id,case_excepted,case_data)
# 关闭工作薄
wb.close()


案例二、

按行读取数据,存储在列表中

import openpyxl
class Case: #这个类用来存储用例的__slots__ = [] #特殊的类属性,可以用来限制这个类创建的实例属性添加 可写可不写passclass ReadExcel(object): #读取excel数据的类def __init__(self,file_name,sheet_name):"""这个是用来初始化读取对象的:param file_name: 文件名 ---> str类型:param sheet_name: 表单名 ———> str类型"""# 打开文件self.wb = openpyxl.load_workbook(file_name)# 选择表单self.sh = self.wb[sheet_name]def read_data_line(self):#按行读取数据转化为列表rows_data = list(self.sh.rows)# print(rows_data)# 获取表单的表头信息titles = []for title in rows_data[0]:titles.append(title.value)# print(titles)#定义一个空列表用来存储测试用例cases = []for case in rows_data[1:]:# print(case)data = []for cell in case: #获取一条测试用例数据# print(cell.value)data.append(cell.value)# print(data)#判断该单元格是否为字符串,如果是字符串类型则需要使用eval();如果不是字符串类型则不需要使用eval()#eval()函数用来执行一个字符串表达式,并返回表达式的值。#isinstance()函数来判断一个对象是否是一个已知的类型if isinstance(cell.value,str):data.append(eval(cell.value))else:data.append(cell.value)#将该条数据存放至cases中# print(dict(list(zip(titles,data))))#zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表"""x = [1, 2, 3]y = [4, 5, 6]z = [7, 8, 9]xyz = zip(x, y, z)print xyz运行的结果是:[(1, 4, 7), (2, 5, 8), (3, 6, 9)]"""case_data = dict(list(zip(titles,data)))cases.append(case_data)return cases
if __name__ == '__main__':r = ReadExcel('cases.xlsx','Sheet1')data1 = r.read_data_line()print(data1)

案例三、

按行读取数据,存储在对象中

import openpyxl
class Case:pass
class ReadExcel(object):def __init__(self,filename,sheetname):self.wb = openpyxl.load_workbook(filename)self.sh = self.wb[sheetname]def read_data_obj(self):"""按行读取数据  每条用例存储在一个对象中:return:"""rows_data = list(self.sh.rows)# print(rows_data)# 获取表单的表头信息titles = []for title in rows_data[0]:titles.append(title.value)# print(titles)# 定义一个空列表用来存储测试用例cases = []for case in rows_data[1:]:# print(case)#创建一个Case类的对象,用来保存用例数据case_obj = Case()data = []for cell in case:  # 获取一条测试用例数据# print(cell.value)# data.append(cell.value)# print(data)if isinstance(cell.value,str):  # 判断该单元格是否为字符串,如果是字符串类型则需要使用eval();如果不是字符串类型则不需要使用eval()data.append(eval(cell.value))else:data.append(cell.value)# 将该条数据存放至cases中# print(dict(list(zip(titles,data))))case_data = list(zip(titles, data))# print(case_data)for i in case_data:setattr(case_obj,i[0],i[1])# print(case_obj)# print(case_obj.case_id,case_obj.data,case_obj.excepted)cases.append(case_obj)return cases
if  __name__ == '__main__':r = ReadExcel('cases.xlsx','Sheet1')res = r.read_data_obj()for i in res:print(i.caseid, i.excepted, i.data)

案例四、

将测试用例封装到列表中,读取指定列的数据

import openpyxl
class Case:pass
class ReadExcelZy(object):def __init__(self,filename,sheetname):self.wb = openpyxl.load_workbook(filename)self.sheet = self.wb[sheetname]# list1 参数为一个列表,传入的是指定读取数据的列,比如[1,2,3]# 每一行[1,3,5]列的数据,读取出来就作为一条测试用例,放在字典中# 所有的用例放在列表中并且进行返回def read_data(self,list1):""":param list1:  list--->要读取列   list类型:return:    返回一个列表,每一个元素为一个用例(用例为dict类型)"""# 获取最大的行数max_r = self.sheet.max_rowcases = []   #定义一个空列表,用来存放所有的用例数据titles = []   #定义一个空列表,用来存放表头# 遍历所有的行数据for row in range(1,max_r+1):if row != 1:      #判断是否是第一行case_data = [] #定义一个空列表,用来存放该行的用例数据for column in list1:info = self.sheet.cell(row,column).value# print(info)case_data.append(info)# print(list(zip(titles,case_data)))case = dict(zip(titles,case_data))  #将该条数据和表头进行打包组合,作用相当于dict(list(zip(titles,case_data)))# print(case)cases.append(case)# print(cases)else:   #获取表头数据for column in list1:title = self.sheet.cell(row,column).valuetitles.append(title)# print(titles)return cases
if __name__ == '__main__':r = ReadExcelZy("cases.xlsx","Sheet1")res = r.read_data([1,2,3])for o in res:print(o['caseid'],o['data'],o['excepted'])

案例五、

将测试用例封装到对象中,读取指定列的数据

import openpyxl
class Case:pass
class ReadExcelZy(object):def __init__(self,filename,sheetname):self.wb = openpyxl.load_workbook(filename)self.sheet = self.wb[sheetname]# list1 参数为一个列表,传入的是指定读取数据的列,比如[1,2,3]# 每一行[1,3,5]列的数据,读取出来就作为一条测试用例,放在字典中# 所有的用例放在对象中并且进行返回def read_data_obj(self,list2):max_r1 = self.sheet.max_row      #获取最大行数cases = []titles = []      #用来存放表头数据for row in range(1,max_r1+1):if row != 1:case_data = []for column in list2:info = self.sheet.cell(row,column).value# print(info)case_data.append(info)cases_data = list(zip(titles,case_data))#将一条用例存到一个对象中(每一列对应对象的一个属性)case_obj = Case()for i in cases_data:# print(i)setattr(case_obj,i[0],i[1])# print(case_obj.caseid,case_obj.excepted,case_obj.data)cases.append(case_obj)else:for column in list2:title = self.sheet.cell(row,column).valuetitles.append(title)return cases
if __name__ == '__main__':r = ReadExcelZy("cases.xlsx","Sheet1")res = r.read_data_obj([1,2,3])for i in res:print(i.caseid,i.data,i.excepted)

案例六、

优化案例五部分代码,将设置对象属性写在初始化方法中(封装Excel类读取数据最常用的方法)

import openpyxl
class Case:  # 这个类用来存储用例的def __init__(self, attrs):"""初始化用例:param attrs:zip类型——>[{key,value},(key1,value1)......]"""for i in attrs:setattr(self, i[0], i[1])
class ReadExcel(object):def __init__(self, filename, sheetname):"""定义需要打开的文件及表名:param filename:   文件名:param sheetname:  表名"""self.wb = openpyxl.load_workbook(filename)self.sheet = self.wb[sheetname]def read_data_obj_new(self, list2):# 获取最大行数max_r1 = self.sheet.max_rowcases = []# 用来存放表头数据titles = []for row in range(1, max_r1 + 1):if row != 1:case_data = []for column in list2:info = self.sheet.cell(row, column).value# print(info)case_data.append(info)case = list(zip(titles, case_data))# 新建对象时,将对象传给Case类case_obj = Case(case)# print(case_obj.caseid,case_obj.excepted,case_obj.data)cases.append(case_obj)else:# 获取表头for column in list2:title = self.sheet.cell(row, column).valuetitles.append(title)if None in titles:raise ValueError("传入的表头的数据有显示为空")return cases
if __name__ == '__main__':r = ReadExcel('cases.xlsx', 'Sheet1')res1 = r.read_data_obj_new([1, 2, 3])for i in res1:print(i.caseid, i.data, i.excepted)

案例七、

将测试数据参数化

import unittest
from python.register_new.register import register
from python.register_new.register_testcase_new import RegisterTestCase
from HTMLTestRunnerNew import HTMLTestRunner
class RegisterTestCase(unittest.TestCase):# 初始化测试用例def __init__(self,modethod_name,excepted,data):# modethod_name 测试用例方法名super().__init__(modethod_name)# excepted 测试用例的预期结果self.excepted = excepted# data 测试用例参数值self.data = datadef setUp(self):print("准备测试环境,执行测试用例之前会执行此操作")def tearDown(self):print("还原测试环境,执行完测试用例之后会执行此操作")def test_register(self):res = register(*self.data)try:self.assertEquals(self.excepted,res)except AssertionError as e:print("该条测试用例执行未通通过")raise eelse:print("该条测试用例执行通过")# 创建测试套件
suite = unittest.TestSuite()# 将测试用例添加至测试套件中
case = [{'excepted':'{"code": 1, "msg": "注册成功"}','data':'('python1', '123456','123456')'},{'excepted':'{"code": 0, "msg": "两次密码不一致"}','data':'('python1', '1234567','123456')'}]
for case in cases:suite.addTest(RegisterTestCase('test_register',case['excepted'],case['data']))# 执行测试套件,生成测试报告
with open("report.html",'wb') as f:runner = HTMLTestRunner(stream = f,verbosity = 2,title = 'python_test_report',description = '这是一份测试报告',tester = 'WL')runner.run(suite)

案例八、

将调用封装好的Excel类的完整代码流程

import unittest
from python.register_new.register import register
from python.register_new.register_testcase_new import RegisterTestCase
from HTMLTestRunnerNew import HTMLTestRunner
from python.readexcel import ReadExcelclass RegisterTestCase(unittest.TestCase):# 初始化测试用例def __init__(self, modethod_name, excepted, data):# modethod_name 测试用例方法名super().__init__(modethod_name)# excepted 测试用例的预期结果self.excepted = excepted# data 测试用例参数值self.data = datadef setUp(self):print("准备测试环境,执行测试用例之前会执行此操作")def tearDown(self):print("还原测试环境,执行完测试用例之后会执行此操作")def test_register(self):res = register(*self.data)try:self.assertEquals(self.excepted, res)except AssertionError as e:print("该条测试用例执行未通通过")raise eelse:print("该条测试用例执行通过")# 创建测试套件
suite = unittest.TestSuite()
# 调用封装好的读取数据的Excel类,获取测试数据
r1 = ReadExcel('cases.xlsx', 'Sheet1')
cases = r1.read_data_obj_new([2, 3])
# 将测试用例添加至测试套件中
for case in cases:# 需要使用eval()函数对except和data进行自动识别suite.addTest(RegisterTestCase('test_register', eval(case.excepted), eval(case.data)))
# 执行测试套件,生成测试报告
with open("report.html", 'wb') as f:runner = HTMLTestRunner(stream=f,verbosity=2,title='python_test_report',description='这是一份测试报告',tester='WL')runner.run(suite)

selenium高级自动化编程相关推荐

  1. linux 运维高级脚本生成器,Linux运维系列,Shell高级脚本自动化编程实战

    课程文件目录: Linux自动化运维系列 Shell高级脚本自动化编程实战 [6.1G] ┣━━01.Shell基础概述 [315.1M] ┃ ┣━━1-1 Shell脚本体系概述.mp4 [154. ...

  2. linux运维脚本编写,最强Linux自动化运维 Shell高级脚本编程实战 带习题+项目实战案例+全套配置脚本...

    最强Linux自动化运维 Shell高级脚本编程实战 带习题+项目实战案例+全套配置脚本 大家可以通过参考下面的课程学习目录,就会发现单单只从目录上来分析就知道这是一部非常系统的Shell自动化脚本运 ...

  3. Python+Selenium 网页自动化 exe 程序编程实现(最全避坑指南)

    前言 在我的日常工作中,经常需要在内网(不连接互联网)的网页版办公系统中进行抓取网页数据.修改表单等大量重复性的操作.我就想是否可以编写出自动化的工具,将这些日常琐碎的操作变得轻松而高效.虽然本人非计 ...

  4. 西门子博途SCL高级博图SCL运动控制自动化项目实例西门子整 套高级SCL编程运动控制

    西门子博途SCL高级博图SCL运动控制自动化项目实例西门子整 套高级SCL编程运动控制

  5. 好书推荐---单片机编程魔法师之高级裸编程思想

    <单片机编程魔法师之高级裸编程思想>以单片机裸环境为基础,为编程者定义了一个微操作系统(MOS)的编程环境,并面向应用中不断提高的需求对编程策略进行了深度剖析与研究,从而分离出数据驱动.并 ...

  6. 西门子 HTML浏览器 上不了网,【高级技巧】PROFINET高级网页编程使用入门

    1 高级网页编程介绍 1.1 描述 PROFINET基于工业以太网,是开放的,标准的,实时的工业以太网标准,这意味着日新月异的以太网IT技术可以融入到PROFINET以及相关的PROFINET产品中. ...

  7. Python爬虫4.4 — selenium高级用法教程

    Python爬虫4.4 - selenium高级用法教程 综述 Headless Chrome 设置请求头 设置代理IP 常用启动项参数options设置 Cookie操作 selenium设置coo ...

  8. 《UNIX高级环境编程》 -- apue.h

    在看<UNIX高级环境编程>这本书的时候,会遇到一个问题就是这个"apue.h",这个是作者为了编写代码方便封装了一个库,我们可以使用下面的方式解决这个问题,让我们的代 ...

  9. Selenium Web 自动化 - Selenium常用API

    Selenium Web 自动化 - Selenium常用API 2016-08-01 目录 1 对浏览器操作   1.1 用webdriver打开一个浏览器   1.2 最大化浏览器&关闭浏 ...

最新文章

  1. Android开发中libs包下面的mips、armeabi、armeabi-v7a和x86
  2. 手机app 有没有window.location.href_热议小程序使用场景越来越多,未来有没有可能替代手机APP?...
  3. Zabbix-Proxy-agent实现web监控
  4. CTF-Python打包成的exe文件Re逆向
  5. python小细节之else
  6. Diango博客--10.交流的桥梁“评论功能”
  7. 实现三联tab切换特效
  8. 带宽和下载速率的关系
  9. ★LeetCode(196)——删除重复的电子邮箱(MySQL)
  10. ios 获取沙盒文件名_IOS获取各种文件目录路径的方法
  11. 每天进步一点点——mysql——Percona XtraBackup(innobackupex)
  12. sqlserver中的函数
  13. excel中怎样制作下拉菜单
  14. 组词组合 php,合组词,合的组词,合字组词,合字的组词,合字能组什么词
  15. python微信群管理开禁言_微信群主怎么禁言别人?微信群怎么让群员禁言?
  16. Oracle的Package的作用及用法
  17. 【Meetup预告】OpenMLDB+37手游:一键查收实时特征计算场景案例及进阶使用攻略
  18. 关卡一: jQuery编程
  19. 导轨电表、万用表、计量插座、工控物联网、学习机、仪器仪表等低功耗高抗干扰段码屏LCD液晶显示驱动IC-VK2C22A/B LQFP52/48,完全兼容替代16C22,44*4/40*4显示
  20. C#技巧 Lazy(延迟初始化)用法

热门文章

  1. [卓意听书]6月感恩活动,Q币送不停!
  2. d3.js 旋转图形_一个简单易用但功能强大的图形矢量化软件,扫描图片转换成CAD图的软件等等...
  3. SEO网站优化方案的五个阶段
  4. 高架桥隔音墙厂家价格@平衡生命
  5. 【面试相关】数据分析面试前必看知识点QA③
  6. TP5.1使用创蓝短信实现验证码的发送以及频控
  7. Python爬虫入门教程 94-100 帮粉丝写Python爬虫之【微信读书书籍信息爬取】
  8. 笛卡尔坐标系与右手定则
  9. mysql数据库学习之sql调优思路
  10. android 群英传笔记,Android 群英传读书笔记1