参数化数据驱动

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了参数化数据驱动相关的知识,希望对你有一定的参考价值。

参考技术A 在自动化测试中,经常会遇到如下场景:

这里只是随意找了两个典型的例子,相信大家都有遇到过很多类似的场景。总结下来,就是在我们的自动化测试脚本中存在参数,并且我们需要采用不同的参数去运行。

经过概括,参数基本上分为两种类型:

然后,对于参数而言,我们可能具有一个参数列表,在脚本运行时需要按照不同的规则去取值,例如顺序取值、随机取值、循环取值等等。

这就是典型的参数化和数据驱动。

如需对某测试用例(testcase)实现参数化数据驱动,需要使用 Parameters 函数,定义参数名称并指定数据源取值方式。

参数名称的定义分为两种情况:

数据源指定支持三种方式:

三种方式可根据实际项目需求进行灵活选择,同时支持多种方式的组合使用。假如测试用例中定义了多个参数,那么测试用例在运行时会对参数进行笛卡尔积组合,覆盖所有参数组合情况。

使用方式概览如下:

将参数名称定义和数据源指定方式进行组合,共有 6 种形式。现分别针对每一类情况进行详细说明。

对于参数列表比较小的情况,最简单的方式是直接在 pytest 中指定参数列表内容。

例如,对于独立参数 password,参数列表为 ['aA123456','A123456',''],那么就可以按照如下方式进行配置:

进行该配置后,测试用例在运行时就会对 password 实现数据驱动,即分别使用 ['aA123456','A123456',''] 三个值运行测试用例。运行日志如下所示:

可以看出,测试用例总共运行了 3 次,并且每次运行时都是采用的不同 password。

对于已有参数列表,并且数据量比较大的情况,比较适合的方式是将参数列表值存储在 CSV 数据文件中。

对于 CSV 数据文件,需要遵循如下几项约定的规则:

例如,password 的参数取值为"aA123456","A123456","" ,那么我们就可以创建 password.csv,并且在文件中按照如下形式进行描述。

然后在 pytest 测试用例文件中,就可以通过内置的 Parameterize(可简写为 P)函数引用 CSV 文件。

假设项目的根目录下有 data 文件夹,password.csv 位于其中,那么 password.csv 的引用描述如下:

即 Parameters 函数的参数(CSV 文件路径)是相对于项目根目录的相对路径。当然,这里也可以使用 CSV 文件在系统中的绝对路径,不过这样的话在项目路径变动时就会出现问题,因此推荐使用相对路径的形式。

对于没有现成参数列表,或者需要更灵活的方式动态生成参数的情况,可以通过在 debugtalk.py 中自定义函数生成参数列表,并在 pytest 引用自定义函数的方式。

例如,若需对 password 进行参数化数据驱动,那么就可以在 debugtalk.py 中定义一个函数,返回参数列表。

然后,在 pytest 的 Parameters 中就可以通过调用自定义函数的形式来指定数据源。

另外,通过函数的传参机制,还可以实现更灵活的参数生成功能,在调用函数时指定需要生成的参数个数。

对于具有关联性的多个参数,例如 username 和 password,那么就可以按照如下方式进行配置:

进行该配置后,测试用例在运行时就会对 password 和 error_code 实现数据驱动,即分别使用
"error_code": "0", "password": "aA123456"、
"error_code": "3007", "password": "A123456"、
"error_code": "3001", "password": ""
运行 3 次测试,并且保证参数值总是成对使用。

对于具有关联性的多个参数,例如 username 和 password,那么就可以创建 username_password_errorCode.csv,并在文件中按照如下形式进行描述。

然后在 pytest 测试用例文件中,就可以通过内置的 parameterize(可简写为 P)函数引用 CSV 文件。

假设项目的根目录下有 data 文件夹,username_password_errorCode.csv 位于其中,那么 username_password_errorCode.csv 的引用描述如下:

对于具有关联性的多个参数,实现方式也类似。
例如,在 debugtalk.py 中定义函数 get_account,生成指定数量的账号密码参数列表。

那么在 pytest 的 Parameters 函数中就可以调用自定义函数生成指定数量的参数列表。

完成以上参数定义和数据源准备工作之后,参数化运行与普通测试用例的运行完全一致。

采用 hrun 命令运行自动化测试:

采用 locusts 命令运行性能测试:

区别在于,自动化测试时遍历一遍后会终止执行,性能测试时每个并发用户都会循环遍历所有参数。

pytest数据参数化和数据驱动yaml的简单使用

Pytest参数化

  • @pytest.mark.parametrize(argnames, argvalues)
  • argnames: 要参数化的变量, string(逗号分隔), list, tuple
  • argvalues: 参数化的值,list, list[tuple]

新建一个 简单的 test_demo.py 代码内容为:

class TestClass:
    @pytest.mark.parametrize(\'a,b\', [(1, 2), (2, 3), (4, 5)])
    def test_a(self, a, b):
        # print(f\'login name is {}\')
        print(a + b)
        print(\'1\')

    def test_b(self):
        print(\'2\')

    def test_c(self, login):
        print(f\'login name is {login}\')
        print(\'3\')
然后在控制台中 输入 上一节 学到的 -k(指定函数) -v(打印详细内容) -s (输出print内容)
pytest -v -k test_a -s

可以看到想要的结果

测试结构化的简单demo

读取yaml文件, 先建立一个数组的demo
yaml的语法 可以参考 https://www.runoob.com/w3cnote/yaml-intro.html

-
  - 10
  - 20
-
  - 30
  - 40

然后建立一个Pytest去读取

import pytest
import yaml

class TestClass:
    @pytest.mark.parametrize(\'a,b\', yaml.safe_load(open(\'env.yml\')))
    def test_a(self, a, b):
        print(a + b)
        print(\'1\')

常常我们需要结构化我们的测试环境,一般配置文件放在yaml中,简单的读取

yml 文件内容:
-
  languages:
    - Ruby
    - Perl
    - Python 
  websites:
    YAML: yaml.org 
    Ruby: ruby-lang.org 
    Python: python.org 
    Perl: use.perl.org

  dev: # 生产环境
    ip: 127.0.0.1

---- # 注意点 当不知道自己写的yml格式对象是否正确的时候可以通过读取出来来验证
class TestClass:
   def test_b(self):
        print(yaml.safe_load(open(\'env.yml\')))
# 然后执行命令行: pytest -v -k test_b -s 就可以看到写的yml

# 下面是读取配置文件的写法,前提是知道自己的yml是什么样子
import pytest
import yaml
class TestClass:
    @pytest.mark.parametrize(\'env\', yaml.safe_load(open(\'env.yml\')))
    def test_a(self, env):
        if "dev" in env:
            # print(env) 可以先打印出来看看 是什么结构
            print(f\'生产环境, ip地址为{env.get("dev").get("ip")}\')
        elif "test" in env:
            print(\'测试环境\')
然后执行命令: pytest -v -k test_a -s 就可以看到执行的结果

下一次随笔写的是测试报告的美化与定制 Allure测试框架的使用

以上是关于参数化数据驱动的主要内容,如果未能解决你的问题,请参考以下文章

参数化之ddt数据驱动框架

pytest之参数化parameterize与数据驱动

行为驱动:Cucumber + Java - 实现数据的参数化

Jmeter 参数化之数据驱动(ddt)

python自动化之数据驱动 - data driven(参数化)

pytest数据参数化和数据驱动yaml的简单使用