很多博主会说UI自动化可以减少成本,提高测试效率。但是它是有一个前提的,就是项目非常稳定,界面不会变。这样的话产出价值才会高。不然的话就是浪费时间。
所以会有人质疑:为什么要做UI自动化呢?其实我本人也是觉得自动化的维护成本很高的,因为系统的界面经常变来变去,很多公司也只会做接口自动化,不会把中心放到UI自动化来。其实有些场景内还是需要做UI自动化的,比如:
1.放在接口自动化做不适合的时候
2.有些功能放在前端进行校验的时候
3.功能反复使用功能的时候
4.项目非常稳定的时候
通过unittest类调用分析,可将框架的工作流程概况如下:
编写TestCase,由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite, 最后将运行的结果保存在TextTestResult中。整个过程集成在unittest.main模块中
我们使用Selenium实现自动化测试,主要需要3个东西:
1.测试脚本,可以是python,java编写的脚本程序(也可以叫做client端)
2.浏览器驱动,这个驱动是根据不同的浏览器开发的,不同的浏览器使用不同的webdriver驱动程序且需要对应相应的浏览器版本
3.浏览器,目前selenium支持市面上大多数浏览器,不同的浏览器使用不同的webdriver驱动程序且需要对应的浏览器版本
先了解下一些方法:
1.定位元素方法,一般需要具备前端HTML和css基础
1.id 通过id获取元素,id一般是唯一值
2.name 通过name属性定位到这个元素
3.class 通过元素的样式class值定位到这个元素
4.css_selector 通过样式选择器定位。操作方法:右键--查看元素,右键--复制唯一元素选择器
5.xpath 通过xpath选择器,通过路径定位,有绝对路径和相对路径
6.tag name 通过标签定位。用得少,如:find_element_by_tag_name("div")
7.link text 通过超链接内容定位,输入全部内容
8.partial link 通过超链接内容定位,输入部分内容
ID定位和xpath定位的区别:
id唯一元素定位。xpath绝对路径和相对路径定位,但是在不同浏览器下对xpath的实现是不一样的,而且XPath会随着页面元素布局的改变而改变,不推荐使用。
2.怎么调起浏览器
webdriver调起firefox()或者Chrome()方法来调起不同浏览器
3.睡眠等待设置
3.1强制等待
from time import sleep
sleep(5)#强制等待5秒
3.2隐形等待
设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步,弊端就是程序会一致等待整个页面加载完成,到浏览器标签栏那个加载圈不再转
可以直接在driver=webdriver.Firefox()下面写上,作用于全局
from selenium import webdriver
driver=webdriver.Firefox()
driver.implicitly_wait(10) #隐形等待,最长10秒
3.3显性等待
WebDriverWait需要配合until和until_not,程序每隔N秒检查一次,如果成功,则执行下一步,否则继续等待,直到超过设置的最长时间
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ES
try:
kw_ele = WebDriverWait(driver,5,0.5).until(ES.presence_of_element_located((By.ID,"kw")))
kw_ele.send_keys("哈哈怪和她的朋友们")
print("资源加载成功")
print(driver.title)
except:
print("资源加载失败")
finally:
print("不管加载成功与否,都打印")
driver.quit()
4.元素在iframe下的要先定位到iframe下
driver.switch_to.frame(frame1)
5.定位弹框
一种是页面可以直接定位的弹框,定位方式查看定位元素方法
一种是windows弹框,无法元素定位的,如:alert,confirm,prompt。用switch_to.alert方法:捕获弹框
alert = driver.switch_to.alert --定位弹框
alert.text --获取弹框文本(多用于alert弹窗)
alert.accept() --点击“确认”(多用于confirm、propmpt弹框上点击确认)
alert.dismiss() --点击“取消”(多用于confirm、propmpt弹框上点击取消)
alert.send_keys() --输入内容(在prompt里使用输入内容)
6.错误截图
driver.get_screenshot_as_file(u"C:\\Users\\哈哈怪\\Desktop\\截图\\login.png")
下面的用例脚本是:登录系统之后,把学校的名字给编辑改名后再删除。并做异常处理抛出异常
#-*- coding: utf-8 -*-
import unittest
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from Util.login_util import LoginTestCaseUtil
class YunTestCase(LoginTestCaseUtil):
def setUp(self):
print("测试开始")
self.driver=webdriver.Firefox()
self.driver.implicitly_wait(10)
self.driver.get("填入系统地址")
self.driver.maximize_window() # 最大化当前页
def tearDown(self):
print("测试结束")
def test_yun(self):
u'云文件'
driver = self.driver
#如果定位的元素在iframe里面,需要先切换到元素所在的frame下
frame1 = driver.find_element_by_css_selector(".index-content-main > iframe:nth-child(1)")
driver.switch_to.frame(frame1)
#编辑
edit_ele = driver.find_element_by_css_selector("div.content-list-item:nth-child(1) > div:nth-child(2) > div:nth-child(1) > i:nth-child(2)")
edit_ele.click()
in_ele = d ver.find_element_by_css_selector("div.content-list-item:nth-child(1) > div:nth-child(2) > div:nth-child(1) > div:nth-child(1) > input:nth-child(1)")
in_ele.click()
clear_ele = driver.find_element_by_css_selector(".el-input__suffix")
clear_ele.click()
in_ele.send_keys("1")
edit_ele.click()
print("-----------改名成功------------")
#搜索
input_ele = driver.find_element_by_css_selector(".el-input--suffix > input:nth-child(1)")
input_ele.send_keys("1")
search_ele = driver.find_element_by_css_selector(".el-button > span:nth-child(1)")
search_ele.click()
print("-----------搜索成功------------")
sleep(2)
#删除
del_ele = driver.find_element_by_css_selector("div.content-list-item:nth-child(1) > div:nth-child(2) > div:nth-child(2) > i:nth-child(2)")
del_ele.click()
del_sure_ele = driver.find_element_by_css_selector("button.el-button--default:nth-child(2) > span:nth-child(1)")
del_sure_ele.click()
try:
driver.find_element_by_css_selector(".el-message__content")
print("-----------删除成功------------")
except Exception as e:
print("删除异常原因:", e)
#错误截图
driver.get_screenshot_as_file(u"C:\\Users\\哈哈怪\\Desktop\\截图\\login.png")
import HTMLTestRunner
import unittest
import time
import sys
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
file = time.strftime("%Y-%m-%d %H_%M_%S", time.localtime())
fp = open("./" + file + "_result.html", "wb")
#标题
title = u"自动化测试报告"
#描述
discription = u"测试结果如下"
if __name__ == '__main__':
# 导入测试用例
suite = unittest.TestSuite()
discover = unittest.defaultTestLoader.discover("../Case", pattern="*case.py", top_level_dir=None)
suite.addTest(discover)
# 生成测试报告
runner = HTMLTestRunner.HTMLTestRunner(
stream=fp,
title=title,
description=discription,
verbosity=2
)
runner.run(suite)
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
#定义发件人、收件人、授权码、主题、文件名称、附件名称
sender = "[email protected]"
receiver = ["[email protected]", "[email protected]"]
auth_code = "dsfdghgjtygb"
subject = u"自动化测试报告"
old_file = "../Run/2022-12-10 09_21_25_result.html"
fn = "测试报告.html"
#导入报告内容
with open(old_file, "rb") as f_obj:
content = f_obj.read()
f_obj.close()
#将content放入邮件正文
zhengwen = MIMEText(content, _subtype="html", _charset="utf-8")
#导入附件
fujian = MIMEText(content, "base64", "gb2312")
fujian["Content-Type"] = "application/octet-stream"
fujian.add_header("Content-Disposition", "attachment", filename=fn)
#定义邮件,加载正文和附件进来
msg=MIMEMultipart()
msg["Subject"]=subject
msg.attach(zhengwen)
msg.attach(fujian)
msg["from"] = sender
msg["to"] = ','.join(receiver)
#发送邮件
smtp = smtplib.SMTP_SSL("smtp.163.com", 465)
smtp.login(sender, auth_code)
smtp.sendmail(sender, msg["to"].split(','), msg.as_string())
smtp.quit()#退出
发送邮件后就可以在收件箱查看邮件附件的执行结果了
以上