pytest实战技巧之参数化基本用法和多种方式

 更新时间:2023年12月08日 09:18:09   作者:自动化测试老司 机  
本文介绍了pytest参数化的基本用法和多种方式,帮助读者更好地使用这个功能,同时,还介绍了一些高级技巧,如动态生成参数名称、参数化的组合和动态生成参数化装饰器,帮助读者更灵活地使用参数化,感兴趣的朋友参考下吧

pytest是Python中最流行的测试框架之一。它提供了丰富的功能,可以帮助我们编写高效、可靠的测试用例。其中一个重要的功能就是参数化,它可以让我们用不同的数据组合来运行同一个测试用例,从而 提高测试覆盖率和效率。本文将介绍pytest参数化的基本用法和一些高级技巧,帮助读者更好地使用这个功能。 

01、基本用法

pytest参数化的基本用法非常简单,只需要在测试函数上添加一个装饰器@pytest.mark.parametrize, 然后指定参数名称和参数值列表即可。例如,我们有一个测试函数test_add,用来测试两个数相加的结果是否正确:

def test_add():
   assert add(2, 3) == 5
   assert add(-1, 1) == 0

现在我们想用多组数据来运行这个测试函数,可以这样做:

import pytest
@pytest.mark.parametrize("a, b, expected", [
  (2, 3, 5),
  (-1, 1, 0),
  (0, 0, 0),
  (100, -100, 0),
])
def test_add(a, b, expected):
   assert add(a, b) == expected

这里我们定义了一个参数化装饰器,指定了三个参数名称a、b和expected,以及一个参数值列表,其中每个元素都是一个包含三个值的元组,分别代表两个数和它们的和。这样,pytest就会根据这个参数值列表,自动运行测试函数四次,每次用一个元组中的数据来替换a、b和expected参数,然后执行断言操作,最后输出测试结果。 

02、参数化的多种方式 

除了上面的方式,pytest还支持多种参数化的方式,可以根据实际情况选择最合适的一种。 

参数值列表 

我们已经看到了最简单的参数化方式,就是将多组参数值放在一个列表中,然后传给装饰器。这种方式适用于参数比较少、每个参数值都比较独立的情况。如果参数值之间有一定的关联性,或者参数比较 多,就不太适合使用这种方式了。 

参数名称列表 

有时我们希望将参数值列表和参数名称列表分开定义,这样可以更清晰地表达参数之间的关系。例如, 我们有一个函数用来测试字符串是否包含某个子串,可以这样写:

@pytest.mark.parametrize("s, sub, expected", [
  ("hello world", "hello", True),
  ("hello world", "world", True),
  ("hello world", "python", False),
])
def test_contains(s, sub, expected):
   assert (sub in s) == expected

这里我们将参数名称s、sub和expected分别和参数值列表中的元组对应起来,这样就可以更直观地理解 每个参数的含义。

注意,参数名称列表也可以是一个字符串,多个参数名称之间用逗号隔开,例如:"a, b, expected"。 

参数化装饰器嵌套 

有时我们需要对多个参数进行组合,这时可以使用参数化装饰器的嵌套。例如,我们有一个函数用来测试两个字符串连接后的结果是否正确,可以这样写:

@pytest.mark.parametrize("s1", ["hello", "world"])
@pytest.mark.parametrize("s2", ["python", "pytest"])
def test_concat(s1, s2):
   assert concat(s1, s2) == s1 + s2

这里我们先用一个参数化装饰器指定s1参数的取值范围,然后在这个装饰器内部再嵌套一个参数化装饰器,指定s2参数的取值范围。这样,pytest就会自动运行测试函数四次,每次用一个s1和一个s2的组合 来测试函数的正确性。 

参数化函数 

有时我们需要动态生成参数值列表,这时可以使用参数化函数。例如,我们有一个函数用来测试一个整数是否为质数,可以这样写:

def is_prime(n):
   if n < 2:
      return False
   for i in range(2, int(n ** 0.5) + 1):
      if n % i == 0:
         return False
   return True
@pytest.mark.parametrize("n", range(10))
def test_is_prime(n):
   assert is_prime(n) == (n in [2, 3, 5, 7])

这里我们使用了Python内置的range函数来生成一个整数序列,然后将这个序列作为参数值列表传给了参数化装饰器。这样,pytest就会自动运行测试函数十次,每次用一个整数来测试函数的正确性。

从文件读取参数 

有时我们需要从外部文件中读取参数值列表,这时可以使用pytest的fixture机制。例如,我们有一个CSV文件,包含了多组数据,每组数据都是一个整数和一个字符串,用逗号隔开。我们希望用这些数据 来测试一个函数,可以这样写:

import csv
import pytest
@pytest.fixture(scope="module")
def data():
   with open("test_data.csv") as f:
      reader = csv.reader(f)
      return list(reader)
@pytest.mark.parametrize("n, s", data())
def test_func(n, s):
   assert func(n, s) == ...

这里我们定义了一个fixture函数data,用来读取CSV文件中的数据,并返回一个列表,每个元素都是一 个包含两个值的元组。然后在测试函数的参数化装饰器中,使用data()来获取这个列表,并将其中的元 组分别赋值给n和s两个参数。这样,pytest就会自动运行测试函数多次,每次用一个元组中的数据来测 试函数的正确性。 

03、参数化的高级技巧 

除了上面介绍的基本用法和多种方式,pytest参数化还有一些高级技巧,可以帮助我们更灵活地使用这个功能。 

动态生成参数名称 

有时我们需要动态生成参数名称,例如根据参数值来生成一个唯一的标识符。这时可以使用pytest的ids 参数,它可以指定每个参数值对应的参数名称。例如,我们有一个函数用来测试两个字符串连接后的长度是否正确,可以这样写:

@pytest.mark.parametrize("s1, s2, expected", [
   ("hello", "world", 10),
   ("pytest", "is awesome", 15),
], ids=["case1", "case2"])
def test_len(s1, s2, expected):
   assert len(concat(s1, s2)) == expected

这里我们使用了ids参数,将每个参数值对应的参数名称指定为了一个字符串,分别 是"case1"和"case2"。这样,pytest就会在测试结果中显示这些参数名称,方便我们查看和分析测试结果。 

参数化的组合 

有时我们需要对多个参数进行组合,例如测试一个函数在不同参数组合下的正确性。这时可以使用pytest的product参数化,它可以将多个参数值列表进行组合,生成所有可能的参数组合。

例如,我们有一个函数用来测试两个整数相乘的结果是否正确,可以这样写:

@pytest.mark.parametrize("a", [1, 2, 3]) @pytest.mark.parametrize("b", [4, 5, 6])
def test_mul(a, b):
   assert mul(a, b) == a * b
@pytest.mark.parametrize("a, b", product([1, 2, 3], [4, 5, 6]))
def test_mul2(a, b):
   assert mul(a, b) == a * b

这里我们先用两个参数化装饰器分别指定a和b的取值范围,然后在测试函数中用a和b的乘积来进行断 言。这样,pytest就会自动运行测试函数九次,每次用一个a和一个b的组合来测试函数的正确性。另 外,我们还可以使用product函数来完成同样的功能,它可以将多个参数值列表进行组合,并返回所有可能的参数组合。

动态生成参数化装饰器 

有时我们需要根据某些条件动态生成参数化装饰器,例如根据某个配置文件中的参数来决定测试函数的参数取值范围。这时可以使用pytest的fixture机制,动态生成参数化装饰器。

例如,我们有一个配置文件,包含了两个参数s和n,分别表示一个字符串和一个整数,我们希望用这些参数来测试一个函数,可 以这样写:

import yaml
import pytest
@pytest.fixture(scope="module")
def config():
   with open("test_config.yaml") as f:
        return yaml.safe_load(f)
@pytest.fixture(scope="module")
   def params(config):
       return [(s, n) for s in config["strings"] for n in config["numbers"]]
def test_func(params):
   for s, n in params:
       assert func(s, n) == ...

这里我们定义了两个fixture函数,config和params。

  • config用来读取配置文件中的参数
  • params用来根据这些参数动态生成参数值列表

然后在测试函数中,使用params来获取参数值列表,并将其中的元 组分别赋值给s和n两个参数。这样,pytest就会自动运行测试函数多次,每次用一个元组中的数据来测试函数的正确性。 

04、总结

本文介绍了pytest参数化的基本用法和多种方式,帮助读者更好地使用这个功能。同时,还介绍了一些高级技巧,如动态生成参数名称、参数化的组合和动态生成参数化装饰器,帮助读者更灵活地使用参数 化。通过学习本文,读者可以更好地理解pytest参数化的原理和用法,从而编写更高效、可靠的测试用例。

到此这篇关于pytest实战技巧之参数化应用的文章就介绍到这了,更多相关pytest参数化应用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 零基础写python爬虫之使用Scrapy框架编写爬虫

    零基础写python爬虫之使用Scrapy框架编写爬虫

    前面的文章我们介绍了Python爬虫框架Scrapy的安装与配置等基本资料,本文我们就来看看如何使用Scrapy框架方便快捷的抓取一个网站的内容,随便选个小站(dmoz.org)来示例吧
    2014-11-11
  • Python 读取 Word 文档操作

    Python 读取 Word 文档操作

    这篇文章主要介绍了Python读取Word文档操作,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • Python新手学习装饰器

    Python新手学习装饰器

    在本篇文章里小编给大家整理的是一篇关于Python装饰器的相关知识点内容,需要的朋友们可以学习下。
    2020-06-06
  • 简单的Python的curses库使用教程

    简单的Python的curses库使用教程

    这篇文章主要介绍了简单的Python的curses库使用教程,来自IBM官方开发者技术文档,需要的朋友可以参考下
    2015-04-04
  • Python 实现简单的shell sed替换功能(实例讲解)

    Python 实现简单的shell sed替换功能(实例讲解)

    下面小编就为大家带来一篇Python 实现简单的shell sed替换功能(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • python+html实现免费在线行为验证保护账号安全

    python+html实现免费在线行为验证保护账号安全

    这篇文章主要为大家介绍了python+html免费在线行为验证保护账号安全实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Python学习之str 以及常用的命令

    Python学习之str 以及常用的命令

    下面小编就为大家带来一篇Python的str 以及常用的命令。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-10-10
  • Django框架 querySet功能解析

    Django框架 querySet功能解析

    这篇文章主要介绍了Django框架 querySet功能解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • 八个超级好用的Python自动化脚本(小结)

    八个超级好用的Python自动化脚本(小结)

    每天你都可能会执行许多重复的任务,例如阅读新闻、发邮件、查看天气、打开书签、清理文件夹等等,本文主要介绍了Python自动化脚本,具有一定的参考价值,感兴趣的可以了解一下
    2022-07-07
  • Python基于time模块求程序运行时间的方法

    Python基于time模块求程序运行时间的方法

    这篇文章主要介绍了Python基于time模块求程序运行时间的方法,涉及Python time模块的使用及数值运算相关操作技巧,需要的朋友可以参考下
    2017-09-09

最新评论