selenium
unittest框架
pytest
unittest框架是基于UI界面的单元功能测试框架(黑盒测试)
Java单元测试框架 Junit (白盒测试)
- 测试固件
setUp() :进行初始化工作
tearDown():进行测试完成后的清理工作 - 测试用例TestCase
测试方法:test_开头 - 批量执行
把多个测试用例(可以是一个脚本,也可以是多个脚本)放到一个测试套件中去执行 - 执行测试用例
TestRunner - 生成测试报告
HTMLRunner
from selenium import webdriver
import unittest
import time
import os
# 继承
class Baidu1(unittest.TestCase):
# 测试固件
# 每个测试方法之前运行
def setUp(self):
# 全局变量 self.
print("--------setUp-------")
self.driver = webdriver.Chrome()
self.url = "https://www.baidu.com/"
self.driver.maximize_window()
time.sleep(3)
# 每个测试方法之后运行
def tearDown(self):
print("--------tearDown-------")
self.driver.quit()
# 测试方法(用例)
def test_hao(self):
driver = self.driver
url = self.url
driver.get(url)
driver.find_element_by_link_text("hao123").click()
time.sleep(6)
# 测试方法要以test_开头
def test_baidu(self):
driver = self.driver
url = self.url
driver.get(url)
driver.find_element_by_id("kw").send_keys("姜云升")
driver.find_element_by_id("su").click()
time.sleep(6)
# 没调用不会执行
def saveScreenAsPhoto(self, driver, file_name):
if not os.path.exists("./image"):
os.makedirs("./image")
now = time.strftime("%Y%m%d-%H%M%S", time.localtime(time.time()))
driver.get_screenshot_as_file("./image/" + now + "-" + file_name)
time.sleep(3)
if __name__ == "__main__":
unittest.main(verbosity=0)
测试套件
- addTest
将类里面的测试方法一个一个添加到测试套件里,运行测试套件
import unittest
from test0720 import test1
def createsuite():
# addTest
suite = unittest.TestSuite()
suite.addTest(test1.Baidu1("test_hao"))
suite.addTest(test1.Baidu1("test_baidu"))
return suite
if __name__ == "__main__":
suite = createsuite()
# verbosity=1 每运行成功一个会有一个.,运行错误F
# verbosity=2 运行细节标注
# 所以参数代表输出结果的详细程度
runner = unittest.TextTestRunner(verbosity=0)
runner.run(suite)
verbosity
0 ( 静默模式): 你只能获得总的测试用例数和总的结果比如总共100个,失败20,成功80
1 ( 默认模式): 非常类似静默模式只是在每个成功的用例前面有个“ . ” 每个失败的用例前面有个“F”
2 ( 详细模式): 测试结果会显示每个测试用例的所有相关的信息
eg:
verbosity=0
verbosity=1
verbosity=2
- makesuit
unittest.makesuit
一次性导入所有脚本(test_),不用一个个add
def createsuite():
# makeSuit
# 一次性导入所有脚本(test_)
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(test1.Baidu1))
return suite
- TestLoader
unittest.TestLoader.loadTestsFromTestCase
先把测试用例放到一个小的套件里,最终把小套件组织到大套件执行
def createsuite():
# TestLoader
suite1 = unittest.TestLoader.loadTestsFromTestCase(test1.Baidu1)
suite2 = unittest.TestLoader.loadTestsFromTestCase(test2.Baidu2)
suite = unittest.TestLoader([suite1,suite2])
return suite
- discover
执行某个文件夹下的所有某种类型或某种格式命名的所有文件的脚本
def createsuite():
# discover
discover = unittest.defaultTestLoader.discover("../test0720", pattern="test*.py", top_level_dir=None)
print(discover)
return discover
测试用例的执行顺序
按照ASCⅡ码的顺序:0 ~ 9,A ~ Z,a ~ z
# 忽略测试用例执行
@unittest.skip("skipping")
unittest断言
在执行测试用例过程中,测试执行成功与否,是通过实际结果和预期结果比较得到的。验证case的结果, 一般来说,如果给定的断言通过, 测试会继续执行到下一行的代码, 如果断言失败, 对应的case测试会立即停止或者生成错误信息( 一般打印错误信息即可) ,但是不要影响其他的case执行
from selenium import webdriver
import unittest
import time
import os
# 继承
class Baidu1(unittest.TestCase):
# 测试固件
# 每个测试方法之前运行
def setUp(self):
# 全局变量 self.
print("--------setUp-------")
self.driver = webdriver.Chrome()
self.url = "https://www.baidu.com/"
self.driver.maximize_window()
time.sleep(3)
# 每个测试方法之后运行
def tearDown(self):
print("--------tearDown-------")
self.driver.quit()
def test_baidu(self):
driver = self.driver
url = self.url
driver.get(url)
driver.find_element_by_id("kw").send_keys("姜云升")
driver.find_element_by_id("su").click()
# 断言
time.sleep(5)
print(driver.title)
self.assertEqual(driver.title, "百度一下_百度搜索", msg="不相等")
# self.assertNotEqual(driver.title, "百度一下_百度搜索", msg="不相等")
# self.assertTrue("cat" == "dog", msg="不相等")
time.sleep(6)
if __name__ == "__main__":
unittest.main(verbosity=0)
HTML报告生成
将HTMLTestRunner.py 放到安装路径下
import HTMLTestRunner
import sys
import time
import unittest
import os
def createsuite():
# discover
# 执行某个文件夹下的所有某种类型或某种格式命名的所有文件的脚本
discover = unittest.defaultTestLoader.discover("../test0720", pattern="test*.py", top_level_dir=None)
print(discover)
return discover
if __name__ == "__main__":
# HTML报告生成
# 1. 创建一个文件夹
curpath = sys.path[0]
# sys.path 是一个路径集合数组
print(sys.path)
print(sys.path[0])
# 当当前路径下resultreport文件夹不存在时,就创建一个
if not os.path.exists(curpath+'/resultreport'):
os.makedirs(curpath+'/resultreport')
# 2. 解决重复命名问题
now = time.strftime("%Y-%m-%d-%H %M %S", time.localtime(time.time()))
print(time.time())
print(time.localtime(time.time()))
# 文件名是路径加上文件的名称
filename = curpath+'/resultreport/'+ now + 'resultreport.html'
# 打开HTML文件,写入测试套件运行结果
# fp 输入流
with open(filename, 'wb') as fp:
# 括号内参数是HTML报告里的参数
runner = HTMLTestRunner.HTMLTestRunner(
stream=fp,
title=u"测试报告",
description=u"用例执行情况",
verbosity=2
)
suite = createsuite()
runner.run(suite)
异常捕捉与错误截图
from selenium import webdriver
import unittest
import time
import os
from selenium.common.exceptions import NoAlertPresentException
from selenium.common.exceptions import NoSuchElementException
# 继承
class Baidu1(unittest.TestCase):
# 测试固件
# 每个测试方法之前运行
def setUp(self):
# 全局变量 self.
print("--------setUp-------")
self.driver = webdriver.Chrome()
self.url = "https://www.baidu.com/"
self.driver.maximize_window()
time.sleep(3)
# 每个测试方法之后运行
def tearDown(self):
print("--------tearDown-------")
self.driver.quit()
def test_baidu(self):
driver = self.driver
url = self.url
driver.get(url)
driver.find_element_by_id("kw").send_keys("姜云升")
driver.find_element_by_id("su").click()
time.sleep(5)
print(driver.title)
# 异常捕捉 错误截图
try:
self.assertEqual(u"ddd百度一下_你就知道", driver.title)
except:
# 出现异常就调用截图函数截图
self.saveScreenAsPhoto(driver, "hao.png")
time.sleep(6)
# 错误截图函数(参数:驱动,截图名字)
def saveScreenAsPhoto(self, driver, file_name):
if not os.path.exists("./image"):
os.makedirs("./image")
now = time.strftime("%Y%m%d-%H%M%S", time.localtime(time.time()))
# 获取当前画面的截图
driver.get_screenshot_as_file("./image/" + now + "-" + file_name)
time.sleep(3)
if __name__ == "__main__":
unittest.main(verbosity=0)
数据驱动
安装ddt
pip install ddt
查看是否安装好
pip show ddt
from selenium import webdriver
import unittest
import time
from ddt import ddt, unpack, data, file_data
import sys, csv
# 文本格式化方法
def getCsv(file_name):
rows = []
path = sys.path[0]
with open(path + '/data/' + file_name, 'rt') as f:
readers = csv.reader(f, delimiter=',', quotechar='|')
next(readers, None)
for row in readers:
temprows = []
for i in row:
# 读每一行的数据
temprows.append(i)
rows.append(temprows)
return rows
@ddt
class Baidu(unittest.TestCase):
# 测试固件
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(30)
self.base_url = "http://www.baidu.com/"
self.driver.maximize_window()
self.verificationErrors = []
self.accept_next_alert = True
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
# @data("姜云升", "娱乐", "新闻", "体育")
# @file_data('test_baidu_data.json')
# @data(["自白书", "自白书_百度搜索"], ["体育", "体育_百度搜索"], ["新闻", "新闻_百度搜索"])
@data(*getCsv('test_baidu_data.txt'))
@unpack
def test_baidu1(self, value):
driver = self.driver
driver.get(self.base_url + "/")
driver.maximize_window()
driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys(value)
driver.find_element_by_id("su").click()
# time.sleep(6)
# self.assertEqual(driver.title, expected_value, msg="搜索结果和期望不一致!")
time.sleep(3)
if __name__ == "__main__":
unittest.main(verbosity=0)