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  ...............快速教你如何搭建关键字驱动自动化测试框架

 

 

posted on 2021-04-09 18:23  chen_2987  阅读(144)  评论(0)    收藏  举报

导航