unittest使用方法记录
概述:
在使用unittest时,对遇到的一些问题整理方便以后使用;
1.自定义传参
chen.py
#!/usr/bin/python # -*- coding: UTF-8 -*- import unittest import requests from ddt import ddt, data, unpack ''' ParametrizedTestCase类:只是装饰处理函数的 TestOne类:是调用函数执行,判断的 ''' class ParametrizedTestCase(unittest.TestCase): def __init__(self, methodName='runTest', param=None): super(ParametrizedTestCase, self).__init__(methodName) self.param = param @staticmethod def parametrize(testcase_klass, param=None): #实例化TestLoader的对象 testloader = unittest.TestLoader() testnames = testloader.getTestCaseNames(testcase_klass) suite = unittest.TestSuite()#创建测试集 for name in testnames: suite.addTest(testcase_klass(name, param=param)) return suite ##################################################### ##用法-testcase(继承于ParametrizedTestCase类) class TestOne(ParametrizedTestCase): def test_01(self): r=requests.get(url=self.param) print(r.text) print ('param =', self.param) #self.assertIn('北京',r.text) self.assertRegexpMatches(r.text,'city', msg = '信息匹配不一致') def test_02(self): self.assertEqual(2, 2, msg = '匹配失败')#断言成功 def test_03(self): self.assertEqual(2, 3, msg = '匹配失败')#断言失败 if __name__ == '__main__': ##用法-1 # suite = unittest.TestSuite()#创建测试套件 # suite.addTest(ParametrizedTestCase.parametrize(TestOne, param='chenwei'))#加载测试方法 # #suite.addTest(ParametrizedTestCase.parametrize(TestOne, param=13)) # unittest.TextTestRunner(verbosity=1).run(suite)#执行用例 ##用法-2 suite = unittest.TestSuite()#创建测试套件 ##从类中的函数调用(只执行指定函数体) tests = [TestOne('test_01',param="https://qqlykm.cn/api/api/tq.php?city=北京")] ##直接通过类调用(类下面的函数都会执行) #tests = [ParametrizedTestCase.parametrize(TestOne,param='https://api.vvhan.com/api/phone?tel=18612260669')] suite.addTests(tests) runner = unittest.TextTestRunner(verbosity=2) runner.run(suite)
2.unittest封装代码
chen.py
import unittest #单元测试模块 from BeautifulReport import BeautifulReport as bf #导入BeautifulReport模块,这个模块也是生成报告的模块,但是比HTMLTestRunner模板好看 class TestCalc(unittest.TestCase): def setUp(self): #每个用例运行之前运行的 print('setup是啥时候运行的') def tearDown(self): #每个用例运行之后运行的 print('teardown是啥时候运行的') @classmethod def setUpClass(cls): #在所有用例执行之前运行的 print('我是setUpclass,我位于所有用例的开始') @classmethod def tearDownClass(cls): #在所有用例都执行完之后运行的 print('我是tearDownClass,我位于多有用例运行的结束') def testcc(self): #函数名要以test开头,否则不会被执行 '''这是第一个测试用例''' #用例描述,在函数下,用三个单引号里面写用例描述 self.assertEqual(1,1) print('第一个用例,可以在这里调用函数') def testaa(self): '''这个是第二个测试用例''' self.assertEqual(1,1) print('第二个用例') def testdd(self): '''用例描述3''' self.assertEqual(1,2) print('第三个用例') def testbb(self): '''用例描述4''' self.assertEqual(2,2) print('第四个用例') if __name__ == "__main__": unittest.main()
3.加载unittest生成报告
dalan.py方式一:自带报告
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' Created on 2017年9月28日 @author: unittest自动化框架(可以调用) ''' import unittest import os import HTMLTestRunner import time now = time.strftime("%Y-%m-%d %H-%M-%S")#获取当前时间及日期 # 用例路径 case_path = os.path.join(os.getcwd(), r"D:\dalan\API_Automation\data") # 报告存放路径 report_path = os.path.join(os.getcwd(), r"D:\dalan\API_Automation\result") def all_case(): discover = unittest.defaultTestLoader.discover(case_path, pattern="chen.py", top_level_dir=None) print(discover) return discover if __name__ == "__main__": # runner = unittest.TextTestRunner() # runner.run(all_case()) # html报告文件路径 #report_abspath = os.path.join(report_path, now+"result.html")#加now就每次生成一个报告,不加则覆盖 report_abspath = os.path.join(report_path, "result.html") fp = open(report_abspath, "wb") runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title=u'unittest自动化测试报告,测试结果:', description=u'用例执行情况:') # 调用add_case函数返回值 runner.run(all_case()) fp.close()
dalan.py方式二:BeautifulReport报告
#!/usr/bin/env python # -*- coding: utf-8 -*- import unittest import time from BeautifulReport import BeautifulReport as bf now = time.strftime("%Y-%m-%d__%H_%M_%S")#获取当前时间及日期 if __name__ == "__main__": #start_dir用例路径 suite = unittest.defaultTestLoader.discover(start_dir=r'D:\dalan\API_Automation\data',pattern='chen.py') run = bf(suite) #实例化BeautifulReport模块 #description描述,,,log_path报告路径 run.report(filename=now+'report.html',description='csreport',log_path=r'D:/dalan/API_Automation/result/')
4.通过参数化读取execl并生成unittest报告
#!/usr/bin/env python # encoding: utf-8 '''1.执行unitest 2.参数读取execl数据作为参数化 3.请求url ''' # ____________________________________________________________________读取execl_____________________________________________________________________________ import xlrd class ExcelUtil(): def __init__(self, excelPath, sheetName="Sheet1"): # 默认为Sheet1 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.ncols def dict_data(self): r = [] # 用于保存所有行的数据 j = 1 # 遍历行数 for i in range(self.rowNum - 1): s = {} # 从第二行取对应values值 values = self.table.row_values(j) for x in range(self.colNum): s[self.keys[x]] = values[x] # print(s[self.keys[x]])遍历打印每行的每列 r.append(s) j += 1 return r # if __name__ == "__main__": # filepath = r"D:\dalan\API_Automation\data\自动化接口用例.xlsx" # data = ExcelUtil(filepath) # case=data.dict_data()#以列表嵌套字典方式返回 # print(case) # __________________________________________________________________封装请求方法_____________________________________________________________________________ import requests,json class HTTPRequests(object): def __init__(self,): self.req = requests.session() # 依据自己公司的请求头默认值配置 self.head = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; rv:11.0) like Gecko', 'Accept': 'image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, ' 'application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, ' 'application/msword, */*', 'Accept-Language': 'zh-CN'} # 封装自己的get请求,获取资源 def get(self, url='', params='', data='', headers=None, cookies=None, verify=True): if headers is None: headers = self.head # print("请求头是:{}".format(headers)) #response = self.req.get(url, params=params, data=data, headers=headers, cookies=cookies, verify=verify) #get有两种方式data和params response = self.req.get(url, params=params, headers=headers, cookies=cookies, verify=verify) print(response.text) return response.text # 封装自己的post请求,获取资源 def post(self, url='', params='', data='', headers=None, cookies=None, verify=True): if headers is None: headers = self.head if params: response = self.req.post(url, params=params, headers=headers, cookies=cookies, verify=verify) elif data: response = self.req.post(url, data=data, headers=headers, cookies=cookies, verify=verify) change=response.json() reult=json.dumps(change, ensure_ascii=False) print(reult) return reult #根据请求方式-来调用函数 def run_main(self,method,url,data=None,header=None): #print('url:{},请求数据{}'.format(url,data)) res = None if method == 'POST': res = self.post(url,data,header) elif method=='GET': res = self.get(url,data,header) else: res='暂时不支持其他方式请求' return res ##_____________________________________________________dd参数化_接口请求_unittest报告生成___________________________________________________________ import unittest import time from ddt import ddt, data from HTMLTestRunner import HTMLTestRunner from BeautifulReport import BeautifulReport as bf @ddt class MyTest_Case(unittest.TestCase): @data(*(ExcelUtil(r'C:\Users\Administrator\Desktop\自动化接口用例.xlsx').dict_data())) # 拆分list嵌套的字典 def test_case(self, data): '''接口测试''' print('打印每行的url', data['请求url']) r = HTTPRequests() res = r.run_main(data['请求方式'], data['请求url'], data['请求数据'], data['headers']) #验证'中国联通'是否在res里(判断用例是否成功) self.assertIn('中国联通', res, 'title不一致登录失败') if __name__ == '__main__': #unittest.main(verbosity=2)#直接调用 ###执行并生成unitest报告 # suite = unittest.TestSuite() # suite.addTests(unittest.TestLoader().loadTestsFromTestCase(MyTest_Case)) # now = time.strftime('%Y-%m-%d %H_%M_%S') # report_path = r"D:\dalan\API_Automation\result\report.html" # with open(report_path, "wb") as f: # runner = HTMLTestRunner(stream=f, title="Esearch接口测试报告", description="测试用例执行情况", verbosity=2) # runner.run(suite) #执行并生成第三方报告BeautifulReport suite = unittest.TestSuite() #定义一个测试集合 suite.addTest(unittest.makeSuite(MyTest_Case)) #把写的用例加进来(将TestCalc类)加进来 run = bf(suite) #实例化BeautifulReport模块 #filename:测试报告名称(不指定默认文件名为report.html) ,,,,report_dir:报告路径(不指定为当前目录) run.report(filename='test.html',report_dir=r'D:\dalan\API_Automation\result',description='这个描述参数是必填的')
execl内容:

5.unittest异常与截图处理
#####对操作不成功时,希望能够继续执行其他操作,或者是,希望操作不成功时,能够写日志记录 目录 1、常见异常 2、截图处理 3、常见异常 1.NoSuchElementException:没有找到元素 2.NoSuchFrameException:没有找到iframe 3.NoSuchWindowException:没找到窗口句柄handle 4.NoSuchAttributeException:属性错误 5.NoAlertPresentException:没找到alert弹出框 6.ElementNotVisibleException:元素不可见 7.ElementNotSelectableException:元素没有被选中 8.TimeoutException:查找元素超时 2、截图处理 第一步:定义一个截图装饰器 # coding:utf-8 from selenium import webdriver class Screen(object): u'''返个应该截图功能的装饰器''' def __init__(self, driver): self.driver = driver def __call__(self, f): def inner(*args): try: return f(*args) except: import time nowTime =time.strftime("%Y_%m_%d_%H_%M_%S") self.driver.get_screenshot_as_file('%s.jpg' %nowTime) raise return inner 第二步:调用截图功能的装饰器 import unittest class Test(unittest.TestCase): driver = webdriver.Firefox() # 全局参数 driver def setUp(self): self.driver.get("https://www.baidu.com") @Screen(driver) def test01(self): u'''返个是失败的案例''' self.driver.find_element_by_id("11kw").send_keys("python") self.driver.find_element_by_id("su").click() @Screen(driver) def test_02(self): u'''返个是通过的案例''' self.driver.find_element_by_id("kw").send_keys("yoyo") self.driver.find_element_by_id("su").click() def tearDown(self): self.driver.quit() if __name__ == "__main__": unittest.main()
相关连接:
https://mp.weixin.qq.com/s/6DvD1FI3kzdWrmojXPrdLg ............................................unittest执行顺序
https://blog.csdn.net/qq_14920377/article/details/109328557 .................................ddt修改测试用例名称,mk_test_name
https://www.jianshu.com/p/034182e2508a ...............................................................改造BeautifulReport适用于unittest多线程执行,输出测试报告
https://blog.csdn.net/qq13933506749/article/details/119319294 .............................unittest入门并引入多线程
https://blog.csdn.net/luoxuexi2020/article/details/121548203 .................................unittest多线程生成测试报告
www.cnblogs.com/linuxchao/p/linux-python-selenium-keywordFW.html ...............快速教你如何搭建关键字驱动自动化测试框架
浙公网安备 33010602011771号