unittest之DDT接口自动化

列表、元组、字典

1.列表:

1>单维列表取值

a = [1, 2, 3]

print(a[0], a[1])

运行结果:
1 2

2>多维列表取值

a = [[1, 2, 3], [4, 5, 6]]

print(a[0][2], a[1][1])


运行结果:
3 5

元组中的多维列表取值

a = ([1, 2, 3], [4, 5, 6])

print(a[0][2], a[1][1])


运行结果:
3 5

2.元组:

1>单维元组取值

a = (1, 2, 3)

print(a[0], a[1])

运行结果:
1 2

2>多维元组取值

a = ((1, 2, 3), (4, 5, 6))

print(a[0][2], a[1][1])


运行结果:
3 5

列表中的多维元组取值

a = [(1, 2, 3), (4, 5, 6)]

print(a[0][2], a[1][1])


运行结果:
3 5

小结:列表与元组的取值形式一致

3.字典:

1>非键值对字典取值     需先转化为列表(采用list)再取值

a = {7, 8, 9}

print(list(a)[0])


运行结果:

8

2>键值对字段取值

a = {"id": 15, "idd": 19, "iddd": 199}

# 获取key

print(list(a.keys())[0], list(a.keys())[1])

运行结果:

id   idd


# 获取value

print(list(a.values())[0], list(a.values())[1])

运行结果:

15   19

#  直接获取指定key的value
print(a.get('id'))

print('\n')

print(a['iddd'])
运行结果:
15

199
 

# 遍历字典的所有key并获取对应的value
values = []

for key in a:

        values.append(a[key])

print(values)

运行结果:

[15, 19, 199]

#  使用items()方法,结合列表推导式获取所有的key或value

keys = [key for key, value in a.items()]

values = [value for key, value in a.items()]

print(keys, values)

运行结果:

['id', 'idd', 'iddd'] [15, 19, 199]

一、DDT前置用法

1.安装导入ddt模块

pip install ddt

安装完成后可能调用时会存在调用报错的情况,解决方法如下:

file ---> setting ---> Project: ---> Python Interpreter ---> 右边小齿轮 ---> show all ---> 点击加号 ---> Virtualenv Environment ---> 选择New environment ---> Base interpreter选择安装的python.exe

2.在类前先添加注解@ddt;在方法参数用例前添加对应注解,如@data   此子类的父类为ddt

@ddt

class TestCrm(unittest.TestCase):

@data('第一次运行')

def test_case(self, yx1):

示例如下(unittest_ddt.py):

import unittest
from ddt import ddt, data


@ddt
class TestCrm(unittest.TestCase):
    @data('第一次运行')
    def test_case(self, yx1):
        print(yx1)

运行结果:

Ran 1 test in 0.002s

OK
第一次运行

Process finished with exit code 0

二、DDT的入参方法以及多次运行方法

1.单次传入的变量为单个

1>运行一次:(运行单次只需添加一个值即可)
import unittest
from ddt import ddt, data


@ddt
class TestCrm(unittest.TestCase):
    @data('第一次运行')
    def test_case(self, yx1):
        print(yx1)

运行结果:

Ran 1 test in 0.002s

OK
第一次运行

Process finished with exit code 0

2>运行多次:(运行几次就需要添加几个值)
import unittest
from ddt import ddt, data


@ddt
class TestCrm(unittest.TestCase):

    @data('第一次运行', '第二次运行')
    def test_case(self, yx1):
        print(yx1)

运行结果:

Ran 2 tests in 0.003s

OK
第一次运行
第二次运行

Process finished with exit code 0

2.单次传入的变量为多个

单次运行传入多个变量需要运用到:采用列表/元组/字典封装多个值,如果要运行多次,即需要添加多个列表/元组/字典即可运行多次。

注意:封装值的数量严格等于方法测试用例定义变量的数量,不然会导致维度不一致而报错!!!

因为传入的是列表/元组/字典,且一个列表/元组/字典中封装了多个值,所以需要采用解包注解:@unpack        此子类的父类为ddt

1>运行一次:(运行单次只需添加一个封装了多个值的列表/元组/字典即可)
1.1、列表 [ ]

注意:封装值的数量严格等于方法测试用例定义变量的数量,不然会导致维度不一致而报错!!!

import unittest
from ddt import ddt, data, unpack


@ddt
class TestCrm(unittest.TestCase):

    @data(['值1', '值2'])  # 列表有几个值则对应几个变量
    @unpack
    def test_case(self, yx1, yx2):
        print(yx1, yx2)

运行结果:

Ran 1 test in 0.008s

OK
值1 值2

Process finished with exit code 0

1.2、元组 ( )

注意:封装值的数量严格等于方法测试用例定义变量的数量,不然会导致维度不一致而报错!!!

import unittest
from ddt import ddt, data, unpack


@ddt
class TestCrm(unittest.TestCase):

    @data(('值1', '值2'))  # 元组有几个值则对应几个变量
    @unpack
    def test_case(self, yx1, yx2):
        print(yx1, yx2)

运行结果:

Ran 1 test in 0.008s

OK
值1 值2

Process finished with exit code 0

1.3、字典{ }

注意:封装值的数量严格等于方法测试用例定义变量的数量,不然会导致维度不一致而报错!!!

import unittest
from ddt import ddt, data, unpack


@ddt
class TestCrm(unittest.TestCase):

    @data({'Id': 'key为id的值', 'car': 'key为car的值'})  # 字典有几个键值对则对应几个变量,特别注意:方法变量名称只能和字典key保持一致
    @unpack
    def test_case(self, Id, car):
        print(Id, car)

 运行结果:

Ran 1 test in 0.001s

OK
key为id的值 key为car的值

Process finished with exit code 0

方法的传值变量与字典中的key名不一致:

import unittest
from ddt import ddt, data, unpack


@ddt
class TestCrm(unittest.TestCase):

    @data({'Id': 'key为id的值', 'car': 'key为car的值'})  # 字典有几个键值对则对应几个变量,特别注意:方法变量名称只能和字典名称保持一致
    @unpack
    def test_case(self, yx1, yx2):
        print(yx1, yx2)

运行结果:

Ran 1 test in 0.016s

FAILED (errors=1)

Error
Traceback (most recent call last):
  File "", line 59, in testPartExecutor
    yield
  File "", line 628, in run
    testMethod()
  File "", line 221, in wrapper
    return func(self, *args, **kwargs)
TypeError: test_case() got an unexpected keyword argument 'Id'


Assertion failed

方法传参变量的数量不等于封装值的数量:

import unittest
from ddt import ddt, data, unpack


@ddt
class TestCrm(unittest.TestCase):

    @data(('值1', '值2'))  # 字典有几个键值对则对应几个变量,特别注意:方法变量名称只能和字典名称保持一致
    @unpack
    def test_case(self, Id):
        print(Id)

运行结果:

Ran 1 test in 0.002s

FAILED (errors=1)


Error
Traceback (most recent call last):
  File "", line 59, in testPartExecutor
    yield
  File "", line 628, in run
    testMethod()
  File "", line 221, in wrapper
    return func(self, *args, **kwargs)
TypeError: test_case() takes 2 positional arguments but 3 were given


Assertion failed

2>运行多次(运行几次就添加几个封装了多个值的列表/元组/字典即可)

示例如下:

import unittest
from ddt import ddt, data, unpack


@ddt
class TestCrm(unittest.TestCase):

    @data(('值1', '值2'), ('值3', '值4'))
    @unpack
    def test_case(self, yx1, yx2):
        print(yx1, yx2)
        print('\n')

运行结果:

Ran 2 tests in 0.002s

OK

值1 值2


值3 值4

3.yaml文件形式入参

yaml形式文件的样式为:1.以键值对的形式定义

                                        2. - 代表一整个列表

示例(JieKo.yaml):

'''
  1. - 为一个列表
  2.以键值对的形式记录数据
'''
- name: 获取学员信息
  request:  # 请求
    url: https://cent.rrrr.com/app/aiop
    method: get
    param:  # 传参
      sfzh: xysfz
      phone: dianhua
      xyname: xymc
  validate: None  # 返回结果断言

方法获参入参方式:

1.方法用例前采用注解 @file_data        此子类的父类为ddt

2.采用yaml文件形式入参,方法定义变量前需要双重指针(**),代表:变量是为可变长度的变量

def test_case(self, **value): # **为代表可变长度

3.普通获参入参具体示例(unittest_ddt):(取值方式可参考:列表、元组、字典的3.2)

import unittest
from ddt import ddt, file_data


@ddt
class TestCrm(unittest.TestCase):

    @file_data('JieKo.yaml')  # 以字典形式展示
    def test_case(self, **value):  # **为代表可变长度
        print(value)

运行结果:

Ran 1 test in 0.002s

OK

Process finished with exit code 0
{'name': '获取学员信息', 'request': {'url': 'https://cent.rrrr.com/app/aiop', 'method': 'get', 'param': {'sfzh': 'xysfz', 'phone': 'dianhua', 'xyname': 'xymc'}}, 'validate': 'None'}

 可能会出现运行报错,异常情况分析:

如果直接粘贴修改文件后运行,有一定几率会报错

Ran 1 test in 0.002s

FAILED (errors=1)

Error
Traceback (most recent call last):
  File "", line 59, in testPartExecutor
    yield
  File "", line 628, in run
    testMethod()
  File "", line 34, in testFailure
    raise self._exception
  File "", line 169, in loadTestsFromName
    parent, obj = obj, getattr(obj, part)
AttributeError: type object 'TestCrm' has no attribute 'test_case'


Assertion failed

错误原因分析:

查看方法函数定义

def file_data(value, yaml_loader=None):
    """
    Method decorator to add to your test methods.

    Should be added to methods of instances of ``unittest.TestCase``.

    ``value`` should be a path relative to the directory of the file
    containing the decorated ``unittest.TestCase``. The file
    should contain JSON encoded data, that can either be a list or a
    dict.

    In case of a list, each value in the list will correspond to one
    test case, and the value will be concatenated to the test method
    name.

    In case of a dict, keys will be used as suffixes to the name of the
    test case, and values will be fed as test data.

    ``yaml_loader`` can be used to customize yaml deserialization.
    The default is ``None``, which results in using the ``yaml.safe_load``
    method.
    """

 信息提取:

value should be a path relative to the directory of the file containing the decorated unittest.TestCase
value应该是一个相对于包含修饰过的unittest.TestCase的文件目录的路径。

解决办法:

出现以上描述的报错时,可查看右上角下拉框文件选择,会发现有两个测试方法的路径,其中一个会报此错误,故只需要选择路径为需要运行文件的位置或类的位置然后运行即可

可对应精确取值:(取值方式可参考:列表、元组、字典的3.2)

import unittest
from ddt import ddt, file_data


@ddt
class TestCrm(unittest.TestCase):

    @file_data('JieKo.yaml')  # 以字典形式展示
    def test_case(self, **value):  # **为代表可变长度
        print(value['name'])  # 获取最外层的key 打印对应value
        print(value['request']['url'])  # 逐层获取对应的key 打印对应key的value
        print(value['request']['param']['phone'])  # 逐层获取对应的key 打印对应key的value

运行结果:

Ran 1 test in 0.002s

OK

Process finished with exit code 0
获取学员信息
https://cent.rrrr.com/app/aiop
dianhua

还可采用 json、excel、csv等文件形式

4.接口自动化示例:

1.安装导入requests模块

pip install requests

2.接口文档转化,此示例采用yaml文件格式,get请求

注意:get请求入参:params post请求入参:json 或 data(表单)

                文件格式入参:files: media:'路径'

JieKo.yaml

- name: 获取学员信息
  request:  # 请求
    url: https://cent.rrrr.com/app/aiop
    method: get
    param:  # 传参
      sfzh: xysfz
      phone: dianhua
      xyname: xymc
  validate: None  # 返回结果断言

unittest_ddt.py

import unittest
from ddt import ddt, file_data
import requests


@ddt
class TestCrm(unittest.TestCase):

    @file_data('JieKo.yaml')  # 以字典形式展示
    def test_case(self, **value):  # **为代表可变长度
        url = value['request']['url']
        param = value['request']['param']
        # url:传入url  params:传入对应需要的入参
        requests.get(url=url, params=param)

       

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值