目录 1. 语法 2. 测试用例的前后置条件 3. 断言 4. 自动化数据参数化 5. 用例加载到运行生成报告案例
一、Unittest语法
1、命名规则 ①测试文件必需先import unittest ②测试类必须继承unittest.TestCase ③测试方法必须以‘test_’开头,测试类也可以由‘test_’开头 ④测试类必须要有unittest.mian()
二、Unittest用例编写_用例前后置条件
1、setup 用例前置条件 2、TearDown 用例后置条件 3、setUpClass 类前置条件 4、TearDownClass 类后置条件
import unittest
#运行时注意鼠标放的位置
# 定义类 必须继承unittest.TestCase
class Test_add(unittest.TestCase):
@classmethod
#类的前置条件
def setUpClass(cls) -> None:
print("每个类执行之前,运行的")
#前置条件:每条用例执行之前都会执行的这个的条件
def setUp(self):
print("每个方法(用例)执行之前,运行的")
# 定义方法:写在类中的函数,每一个方法对应着一个功能
def test_001(self):
print('jxc你好帅')
# 可以定义多个方法
def test_002(self):
print('第二条测试用例')
#后置条件:每条用例运行之后都会运行的
def tearDown(self) -> None:
print("每个方法(用例)执行之后,运行的")
#类的后置条件
@classmethod
def tearDownClass(cls) -> None:
print("每个类运行完执行之后,运行的")
#总的
if __name__ == '__main__':
unittest.main()
三、Unittest断言
import unittest
'''
assert*():一些断言方法:在执行测试用例的过程中,最终用例是否执行通过,是通过判断测试得到的实际结果和预期结果是否相等决定的。
assertIn(a,b,[msg='测试失败时打印的信息']):断言a是否在b中,在b中则测试用例通过。#包含
assertNotIn(a,b,[msg='测试失败时打印的信息']):断言a是否在b中,不在b中则测试用例通过。
assertEqual(a,b,[msg='测试失败时打印的信息']):断言a和b是否相等,相等则测试用例通过。
assertNotEqual(a,b,[msg='测试失败时打印的信息']):断言a和b是否相等,不相等则测试用例通过。
assertTrue(x,[msg='测试失败时打印的信息']):断言x是否True,是True则测试用例通过。
assertFalse(x,[msg='测试失败时打印的信息']):断言x是否False,是False则测试用例通过。
assertIs(,b,[msg='测试失败时打印的信息']):断言a是否是b,是则测试用例通过。
assertNotIs(a,b,[msg='测试失败时打印的信息']):断言a是否是b,不是则测试用例通过。
assertIsNone(x,[msg='测试失败时打印的信息']):断言x是否None,是None则测试用例通过。
assertIsNotNone(x,[msg='测试失败时打印的信息']):断言x是否None,不是None则测试用例通过。
assertIsInstance(a,b,[msg='测试失败时打印的信息']):断言a是是b的一个实例,是则测试用例通过。
assertNotIsInstance(a,b,[msg='测试失败时打印的信息']):断言a是是b的一个实例,不是则测试用例通过。
'''
# 定义类 必须继承unittest.TestCase
class Test_add(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
print("每个类执行之前,运行的")
def setUp(self):
print("每个方法(用例)执行之前,运行的")
def test_001(self):
print('jxc你好帅')
self.assertEqual(2,1,['返回结果与预期结果不相同'])
def test_002(self):
print('第二条测试用例')
self.assertEqual(1, 1)
def tearDown(self) -> None:
print("每个方法(用例)执行之后,运行的")
@classmethod
def tearDownClass(cls) -> None:
print("每个类运行完执行之后,运行的")
if __name__ == '__main__':
unittest.main()
四、Unittest自动化数据参数化
1、Unittest自带的参数化方法
import form
import unittest
import unittestreport as unittestreport
from selenium import webdriver
from ddt import ddt, data, unpack
'''
①导入ddt库
②把@ddt放到类上
③把@unpack和@data放到对应测试的方法上
④编写测试数据
⑤把测试数据传入到@data中
⑥
'''
# cases = [{'title':'正确的用户名密码登录','data':['4519@qq.com',123456],'expected':'4519@qq.com'},
# 'title':'密码不正确登录']
#
test1 = (['2665249937@qq.com', 123456], ['45194@qq.com', 123456])
@ddt
class Test_login(unittest.TestCase):
def setUp(self) -> None:
self.dr = webdriver.Chrome()
self.dr.maximize_window()
self.dr.implicitly_wait(10)
self.dr.get('http://49.234.61.74/')
self.dr.find_element_by_link_text('登录').click()
@data(*test1) #*test1是一个可变的变量
@unpack #解包
def test_001(self, name, pwd):
dr = self.dr
dr.find_element_by_css_selector("#account").send_keys(name)
dr.find_element_by_name("password").send_keys(pwd)
dr.find_element_by_xpath('//*[@id="main"]/div/div/div/div[2]/div/form/ul/li[5]/button').click()
try:
name1 = dr.find_element_by_xpath('//*[@id="main"]/div[1]/div/div[2]/dl/dd/table/tbody/tr[1]/td/b').text
print(name1)
self.assertEqual(name1, name, msg='登录成功') # 断言
except:
self.assertEqual(1, 2, msg='用户名或密码错误')
def tearDown(self):
self.dr.quit()
2、Unittestreport参数化
import unittest
from unittestreport import ddt,list_data,json_data,rerun
from selenium import webdriver
#一个列表:里面嵌套三个字典数据,一个字典中有三组数据分别表示:用例标题,测试数据,期望结果
cases = [{'title': '正确的用户名密码登录', 'data': ["2665249937@qq.com",123456], 'expected': '2665249937@qq.com'},
{'title': '密码不正确登录', 'data': ["2665249937@qq.com",12345], 'expected': '密码错误!'},
{'title': '用户名不正确', 'data': ["2665249936@qq.com",123456], 'expected': '用户不存在'}]
@ddt
class Test_login(unittest.TestCase):
def setUp(self) -> None:
self.dr = webdriver.Chrome()
self.dr.maximize_window()
self.dr.implicitly_wait(10)
self.dr.get('http://49.234.61.74/')
self.dr.find_element_by_link_text('登录').click()
@list_data(cases)
def test_001(self,case): #这里用的接收数据自定义
#序列解包:从字典中提取数据
name,pwd = case['data'] #相当于一个字典中的:'data': ["4519@qq.com",123456]
dr = self.dr
dr.find_element_by_css_selector("#account").send_keys(name)
dr.find_element_by_name("password").send_keys(pwd)
dr.find_element_by_xpath('//*[@id="main"]/div/div/div/div[2]/div/form/ul/li[5]/button').click()
try:
name1 = dr.find_element_by_xpath('//*[@id="main"]/div[1]/div/div[2]/dl/dd/table/tbody/tr[1]/td/b').text
print(name1)
self.assertEqual(name1, name, msg='登录成功') # 断言
except:
self.assertEqual(1, 2, msg='用户名或密码错误')
def tearDown(self):
self.dr.quit()
3、Unittest_Json传参
(1)json数据文件,文件名aa.json
[{"title": "正确的用户名密码登录", "data": ["4519@qq.com",123456], "expected": "4519@qq.com"},
{"title": "密码不正确登录", "data": ["4519@qq.com",12345], "expected": "密码错误!"},
{"title": "用户名不正确", "data": ["45erer19@qq.com",123456], "expected": "账号不存在!用户不存在!"}]
(2)测试用例执行文件
import unittest
from unittestreport import ddt,list_data,json_data,rerun
from selenium import webdriver
@ddt
class Test_login(unittest.TestCase):
def setUp(self) -> None:
self.dr = webdriver.Chrome()
self.dr.maximize_window()
self.dr.implicitly_wait(10)
self.dr.get('http://49.234.61.74/')
self.dr.find_element_by_link_text('登录').click()
@json_data(r'D:\py\测试班\Unittest框架\aa.json')
def test_001(self,case): #这里用的接收数据自定义
#序列解包:从字典中提取数据
name,pwd = case['data'] #相当于一个字典中的:'data': ["4519@qq.com",123456]
dr = self.dr
dr.find_element_by_css_selector("#account").send_keys(name)
dr.find_element_by_name("password").send_keys(pwd)
dr.find_element_by_xpath('//*[@id="main"]/div/div/div/div[2]/div/form/ul/li[5]/button').click()
try:
name1 = dr.find_element_by_xpath('//*[@id="main"]/div[1]/div/div[2]/dl/dd/table/tbody/tr[1]/td/b').text
print(name1)
self.assertEqual(name1, case["expected"], msg='登录成功') # 断言
except:
#self.assertEqual(1, 2, msg='用户名或密码错误')
self.assertEqual(name1, case["expected"], msg='登录失败') # 断言
def tearDown(self):
self.dr.quit()
五、完整Unittest框架案例_生成测试报告
(1)json数据文件:文件名:aa.json
[{"title": "正确的用户名密码登录", "data": ["4519@qq.com",123456], "expected": "4519@qq.com"},
{"title": "密码不正确登录", "data": ["4519@qq.com",12345], "expected": "密码错误!"},
{"title": "用户名不正确", "data": ["45erer19@qq.com",123456], "expected": "账号不存在!用户不存在!"}]
(2)测试用例文件,文件名:test_login.gy 这里的测试文件一定要用test_开头
import unittest
from datetime import time
from unittestreport import ddt, list_data, json_data, rerun
from selenium import webdriver
@ddt
class Test_login(unittest.TestCase):
def setUp(self) -> None:
self.dr = webdriver.Chrome()
self.dr.maximize_window()
self.dr.implicitly_wait(10)
self.dr.get('http://49.234.61.74/')
self.dr.find_element_by_link_text('登录').click()
@json_data(r'D:\py\测试班\完整Unittest流程\aa.json')
# @unittest.skip #当一个用例上写了@unittest.skip 表示跳过这条用例
def test_001(self, case): # 这里用的接收数据自定义
# 序列解包:从字典中提取数据
name, pwd = case['data'] # 相当于一个字典中的:'data': ["4519@qq.com",123456]
dr = self.dr
dr.find_element_by_css_selector("#account").send_keys(name)
dr.find_element_by_name("password").send_keys(pwd)
dr.find_element_by_xpath('//*[@id="main"]/div/div/div/div[2]/div/form/ul/li[5]/button').click()
try:
name1 = dr.find_element_by_xpath('//*[@id="main"]/div[1]/div/div[2]/dl/dd/table/tbody/tr[1]/td/b').text
print(name1)
self.assertEqual(name1, case["expected"], msg='登录成功') # 断言
except:
now = time.strftime("%Y-%m-%d %H-%M-%S") # 获取系统当前时间
dr.save_screenshot(r"d:\baidu{}.png".format(now)) # 截图
# self.assertEqual(1, 2, msg='用户名或密码错误')
self.assertEqual(name1, case["expected"], msg='登录失败') # 断言
def tearDown(self):
self.dr.quit()
(3)执行测试用例文件,文件名:执行测试用例.py 生成测试报告 给qq邮箱发送测试报告
from unittestreport import TestRunner
import unittestreport
import unittest
import time
#创建一个测试套件
#from 测试班.完整Unittest流程 import Unittest_Json传参
#suite = unittest.TestSuite()
#创建一个用例加载器
#loader = unittest.TestLoader()
#加载用例有几种方法
#①通过模块加载
#suite.addTest(loader.loadTestsFromModule(Unittest_Json传参.py))
#②通过路径加载
#suite = unittest.defaultTestLoader.discover(r'D:\py\测试班\完整Unittest流程\Unittest_Json传参') #最后一级时不需要加后缀名
#第二个参数:加载以pp开头的测试用例,默认是加载以test开头的测试用例
#suite = unittest.defaultTestLoader.discover(r'D:\py\测试班\完整Unittest流程\Unittest_Json传参',pattern='pp*.py')
now = time.strftime('%Y-%m-%d %H-%M-%S')
suite = unittest.defaultTestLoader.discover(r'D:\py\测试班\完整Unittest流程') #最后一级时不需要加后缀名,路径是测试用例的上一级
#生成测试报告
runner = TestRunner(suite,
tester='测试人员—小明',
filename="test_report7{}".format(now), #报告的名字
report_dir=r"D:\py\测试班\完整Unittest流程", #放报告的位置
title='蒋星灿', #测试报告的标题
desc='TinyShop_v3.1项目测试报告', #测试报告的详细描述
templates=1) #测试报告的风格 有三种模板
#运行用例,生成测试报告
runner.run() #失败和成功的用例都只跑一遍
#runner.rerun_run(3,1) #只要用例中出现失败的,都把失败的用例跑三遍
#发送到qq邮箱
# runner.send_email(host="smtp.qq.com",
# port=465,
# user="2665249937@qq.com",
# password="vxzpgfdvgkxfechd", #授权码
# to_addrs="2665249937@qq.com")
|