• 自动化测试中,测试数据与脚本分离以及参数化方法


    测试数据和测试代码在实际的测试工作中,往往是分开存放的,利于测试数据和测试脚本的分开来维护。比如,为测试用例添加几组新的测试数据,只需要修改测试数据文件,测试代码不需要动;如果是测试用例增加了新的校验点,只需要修改测试脚本,不需要修改测试数据文件。

    —、准备测试数据

    现在在data/目录下创建一个用于存放测试数据的Yaml文件test_in_theaters.yaml,内容如下:

    1. ---
    2. tests:
    3. - case: 验证响应中start和count与请求中的参数一致
    4. input:
    5. method: GET
    6. path: /v2/movie/in_theaters
    7. headers:
    8. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36
    9. params:
    10. apikey: 0df993c66c0c636e29ecbb5344252a4a
    11. start: 0
    12. count: 10
    13. expected:
    14. response:
    15. title: 正在上映的电影-上海
    16. count: 10
    17. start: 0
    18. - case: 验证响应中title"正在上映的电影-北京"
    19. input:
    20. method: GET
    21. path: /v2/movie/in_theaters
    22. headers:
    23. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36
    24. params:
    25. apikey: 0df993c66c0c636e29ecbb5344252a4a
    26. start: 1
    27. count: 5
    28. expected:
    29. response:
    30. title: 正在上映的电影-北京
    31. count: 5
    32. start: 1

    熟悉Yaml格式的同学,应该很容易看懂上面测试数据文件的内容。这个测试数据文件中,有一个数组tests,里面包含的是两条完整的测试数据。一个完整的测试数据由三部分组成:

    1. case,表示测试用例名称。

    2. input,表示输入参数。

    3. expected,表示预期结果。

    上面的input输入参数,是一个http请求对象,包含了被测接口的所有参数,包括请求方法、请求路径、请求头、请求参数。expected表示预期结果,上面的测试数据中,只列出了对请求响应的预期值,实际测试中,还可以列出对数据库的预期值。

    二、编写测试脚本

    新建一个测试脚本test_paramtrize_by_data_driven.py,内容如下:

    1. import pytest
    2. class TestDataDriven:
    3. @pytest.mark.datafile('data/test_in_theaters.yaml') # 相对于项目根目录的相对路径
    4. def test_data_driven(self, parameters):
    5. print(parameters['input'])
    6. print(parameters['expected'])

    首先看一下测试函数,在测试函数上方使用了一个叫做datafile的marker来为测试函数提供数据。测试数据的路径是相对于项目根路径的相对路径,这里表示的是测试数据是在项目的根路径下data目录中的test_in_theaters.yaml。测试函数通过parameters这个fixture拿到测试数据内容。

    三、实现pytest_generate_tests Hook

    上面测试脚本使用测试数据的方法,是在tests/conftest.py文件中的pytest_generate_tests函数中实现的。

    1. import yaml
    2. import json
    3. def pytest_generate_tests(metafunc):
    4. ids = []
    5. markers = metafunc.definition.own_markers
    6. for marker in markers:
    7. if marker.name == 'datafile': # 读取外数据
    8. test_data_path = os.path.join(metafunc.config.rootdir, marker.args[0]) # 拼接测试数据路径
    9. with open(test_data_path) as f:
    10. ext = os.path.splitext(test_data_path)[-1]
    11. if ext in ['.yaml', '.yml']:
    12. test_data = yaml.safe_load(f)
    13. elif ext == '.json':
    14. test_data = json.load(f)
    15. else:
    16. raise TypeError('datafile must be yaml or json,root must be tests')
    17. if "parameters" in metafunc.fixturenames: # 用外部数据进行参数化
    18. for data in test_data['tests']: # 用test_data中的case作为测试用例名称
    19. ids.append(data['case'])
    20. # 用test_data这个列表对parameters进行参数化。
    21. metafunc.parametrize("parameters", test_data['tests'], ids=ids, scope=

    metafunc.definition.own_markers可以读取到测试函数中所有的marker,如果存在datafile这个marker,表示需要从外部读取测试数据,测试数据可以是YAML格式也可以是Json格式。如果测试函数的metafunc.fixturenames中含有parameters这个fixture函数,就用外部测试数据对它进行参数化。

    四、参数化套路

    有了pytest_generate_tests这个Hook函数后,对测试函数进行参数化需要做三个改动:

    • 在data目录下新加一个YAML或者Json格式文件。文件内容格式参考上面的例子。

    • 指定测试数据文件的路径@pytest.mark.datafile('data/test_in_theaters.yaml')

    • 给测试数据提供一个叫做 parameters的fixture

    现在,整个项目的目录结构应该是如下所示:

    1. $ tree
    2. .
    3. ├── Pipfile
    4. ├── Pipfile.lock
    5. ├── data
    6. │ └── test_in_theaters.yaml
    7. ├── tests
    8. │ └── conftest.py
    9. │ └── test_data_driven.py

    五、总结

    本文实现测试脚本和测试数据的分离的核心,还是实现了Hook函数,在Hook函数中读取测试数据文件,并对测试函数的fixture进行参数化。

    只是通过一个小小的例子完成了postman关于参数化的介绍,当然小伙伴们需要自己动手操作下才能加深自己的记忆哦

    最后在我的QQ技术交流群里整理了我这10几年软件测试生涯整理的一些技术资料,包括:电子书,简历模块,各种工作模板,面试宝典,自学项目等。如果在学习或工作中遇到问题,群里也会有大神帮忙解答,群号 798478386 ( 备注 今日头条555 )

    全套软件测试自动化测试教学视频

     300G教程资料下载【视频教程+PPT+项目源码】

      全套软件测试自动化测试大厂面经

     

  • 相关阅读:
    Elasticsearch - Elasticsearch 8.X;Elasticsearch 8.X集群(十)
    CreateProcess error=206, 文件名或扩展名太长。
    第九节:类和对象【三】【static、代码块、对象的打印】
    声网实现音频通话
    二 linux操作系统安装git并与gitlab通过SSH方式互通
    手撕指针第一页
    从MVC到DDD,该如何下手重构?
    Vue-router源码-各原理简单总结
    C++ Reference: Standard C++ Library reference: C Library: cwchar: fgetwc
    升级node到指定版本
  • 原文地址:https://blog.csdn.net/caixiangting/article/details/126248154