美文网首页
unittest小结--多种方式

unittest小结--多种方式

作者: 我是孟小鱼呀 | 来源:发表于2019-12-03 14:29 被阅读0次

    前提条件:数据已经存放在excel表格中,数据表名data.xlsx,表单名login_data
    test_http_request.py(unittest)测试http_request.py

    http_request.py
    # -*-coding: utf8 -*-
    
    import requests
    
    class HttpRequest(object):
    
        def http_request(self, url, data, method, expected=None, cookie=None):
            if method.lower() == 'get':
                res = requests.get(url, data=None, cookies=cookie, verify=False)
            else:
                res = requests.post(url, data, cookies=cookie, verify=False)
    
            return res
    

    一、test_http_request

    (1)初始化参数方法,但要超继承
    import unittest
    
    #继承unittest中的类TestCase,用来编写用例
    class TestHttpRequest(unittest.TestCase):
    #保留继承unittest原来的方法,拓展需要的参数
    #初始化函数
        def __init__(self, methodName, url, data, method, expected):#通过初始化函数传参
            super(TestHttpRequest, self).__init__(methodName)#保留父类的方法
            self.url = url
            self.data = data
            self.method = method
            self.expected = expected
        def setUp(self):
            pass
    #测试用例参数化
        def test_api(self):
            res = HttpRequest().http_request(
                self.url,
                self.data,
                self.method,
                self.expected,
                getattr(GetData, 'Cookie')
            )
            if res.cookies:  # 如果cookie有的话,那就更新COOKIE
                setattr(GetData, 'Cookie', res.cookies)
            try:
                self.assertEqual(self.expected, res.json()['info'])
            except AssertionError as e:
                print('test_api的错误是:{}'.format(e))
                raise e
            print(res.json())
    
    (2)ddt方式传数据
    test_data = DoExcel('data_3.xlsx', 'login_data').get_data()
    @ddt
    class TestHttpRequest(unittest.TestCase):
    
        def setUp(self):
            pass
        @data(*test_data)
        def test_api(self, item):
            res = HttpRequest().http_request(
                item['url'],
                eval(item['data']),
                item['method'],
                item['expected'],
                getattr(GetData, 'Cookie')
            )
            if res.cookies:  # 如果cookie有的话,那就更新COOKIE
                setattr(GetData, 'Cookie', res.cookies)
            try:
                self.assertEqual(item['expected'], res.json()['info'])
            except AssertionError as e:
                print('test_api的错误是:{}'.format(e))
                raise e
            print(res.json())
    

    二、test_suite控制测试用例执行

    (1)取数据方法一:全都取出来
    test_data = DoExcel1('data.xlsx', 'login_data').get_data()
    suite = unittest.TestSuite()#加载用例到用例的方法名
    for item in test_data:#从test_data中取数据
        suite.addTest(
            TestHttpRequest(
                'test_api',
                item['url'],
                eval(item['data']),#把字符串转换成原来的格式字典
                item['method'],
                item['expected']
            )
        )
    
    (2)取数据方法二:用哪个取哪个
    t = DoExcel2('data.xlsx', 'login_data')
    suite = unittest.TestSuite()
    for i in range(1, t.max_row + 1):
        suite.addTest(
            TestHttpRequest(
                'test_api',
                t.get_data(i, 1),
                eval(t.get_data(i, 2)),
                t.get_data(i, 3),
                t.get_data(i, 4)
            )
        )
    

    注意:上述两种方法选择一种使用,不是同时使用,推荐使用第一种

    执行用例
    with open('test_login_report.html', 'w', encoding='utf8') as file:
        runner = HTMLTestRunner(
            output="./reports/",
            stream=file,
            verbosity=2,
            descriptions=True
        )
        runner.run(suite)
    

    三、do_excel

    do_excel读数据的目的是为了把返回的数据以列表嵌套字典的形式输出

    (1)方法一:读出全部数据
    # -*-coding: utf8 -*-
    from openpyxl import load_workbook
    class DoExcel1(object):
    
        def __init__(self, file_name, sheet_name):
            self.file_name = file_name
            self.sheet_name = sheet_name
    
        def get_data(self):
            wb = load_workbook(self.file_name)
            sheet = wb[self.sheet_name]
            max_row = sheet.max_row
    
            test_data = []
            for row in range(1, max_row + 1):
                sub_data = {}
                sub_data['url'] = sheet.cell(row, 1).value
                sub_data['data'] = sheet.cell(row, 2).value
                sub_data['expected'] = sheet.cell(row, 3).value
                sub_data['method'] = sheet.cell(row, 4).value
                test_data.append(sub_data)
            return test_data
        #def write_back(self, file_name, sheet_name, row, value):#把结果写回到表中
            #wb = load_workbook(file_name)
            #sheet_name = wb[sheet_name]
            #sheet.cell(row, 5).value = value
            #wb.save(file_name)
    
    (2)方法二:根据坐标取出用到的单元格的值
    class DoExcel2(object):
    
        def __init__(self, file_name, sheet_name):
            self.file_name = file_name
            self.sheet_name = sheet_name
            self.sheet_obj = load_workbook(self.file_name)[self.sheet_name]
            #获取一个表单对象
            self.max_row = self.sheet_obj.max_row
    
        def get_data(self, i, j):
            return self.sheet_obj.cell(i, j).value
            #根据传入的坐标来传值
    
    (3)方法三:表数据中加了标题,通过标题来定位数据(和方法一相同,加了标题)
    class DoExcel3(object):
    
        def __init__(self, file_name, sheet_name):
            self.file_name = file_name
            self.sheet_name = sheet_name
    
        def get_header(self):
            wb = load_workbook(self.file_name)
            sheet = wb[self.sheet_name]
            '''获取第一行标题'''
            header = []
            for column in range(1, sheet.max_column + 1):
                header.append(sheet.cell(1, column).value)
    
            return header
    
        def get_data(self):
            #从配置文件读取mode
            mode = ReadConfig().read_config('case.config', 'MODE', 'mode')
            wb = load_workbook(self.file_name)
            sheet = wb[self.sheet_name]
            max_row = sheet.max_row
            header = self.get_header() #拿到header
    
            test_data = []
            for row in range(2, max_row + 1):
                sub_data = {}
                for column in range(1, sheet.max_column + 1):
                    sub_data[header[column - 1]] = sheet.cell(row, column).value
                test_data.append(sub_data)
            #根据mode值去判断
            if mode == 'all':#默认执行所有用例
                final_data = test_data
            else:#[1, 2, 3, 4]
                final_data = []
                for item in test_data:#对test_data所有的测试数据进行遍历
                    if item['case_id'] in eval(mode):
                        final_data.append(item)
    
            return final_data#返回获取到的数据
    if __name__ == '__main__':
    
        print(DoExcel('data.xlsx', 'login_data').get_data())
    
    补充:上述通过配置文件读取执行用例的条件
    #case.config文件举例
    [MODE]
    mode = all
    
    [PYTHON]
    num = 66
    name = ['aaa','bbb']
    
    import configparser
    #section(中括号[]) option value   #(key:value)
    
    cf = configparser.ConfigParser()
    cf.read('case.config', encoding='utf-8')
    
    #读取配置文件的数据
    #读取方法一
    # res_1 = cf.get('MODE', 'mode')
    # print(res_1)
    #
    # #读取方法二
    # res_2 = cf['MODE']['mode']
    # print(res_2)
    # print(cf.sections())
    # print(cf.items('MODE'))#每一组元素都存在一个元组里面,然后嵌套在一个列表里面
    
    #数据类型讨论问题----都是字符串---->eval()转换字符串
    print(type(cf.get('PYTHON', 'num')))
    print(type(cf.get('PYTHON', 'name')))#配置文件里的内容输出都是字符串
    
    补充:ddt
    import unittest
    from ddt import ddt, data, unpack
    
    test_data = [[1, 4], [2, 3]]
    
    @ddt#装饰测试类
    class TestMath(unittest.TestCase):
    
        # @data(test_data)#装饰测试方法 拿到几个数据 就执行几条用例 一条数据执行1次
        # #@data(*test_data) #拆分开来 执行2次,一个*只能托一层外套
        # #unpack 根据逗号进行拆分,不止一个参数
        @data(test_data)
        @unpack#如果unpack后的参数 少于5个 推荐用unpack
        #要注意参数不对等的情况,提供对应个数的参数来接收变量
        #如果你要对字典进行unpack的 参数名与你的字典key对应
        def test_print_data(self, item):
            print('item', item)
        # def test_print_data(self, a, b):
        #     print('a', a)
        #     print('b', b)
    

    相关文章

      网友评论

          本文标题:unittest小结--多种方式

          本文链接:https://www.haomeiwen.com/subject/znscgctx.html