1. 前言
在软件测试过程中,我们常常需要针对同一功能或场景进行多次测试,对于一些特定的测试,我们需要检查多组数据的输入及输出。这种情况下,用例参数化是一个非常强大的技术。
2. 什么是用例参数化
简单来说,用例参数化指的是在执行同一函数或方法的不同输入时,将输入参数作为测试用例的多组数据来测试。这样的好处在于,我们无需新建多个测试用例,只需要把不同的输入参数作为参数传递给同一函数或方法即可。
2.1 为什么需要用例参数化
使用用例参数化主要有以下几个好处:
提高测试效率,减少冗余的测试用例编写;
提高测试覆盖率,我们可以用不同的参数组合来测试系统的不同行为;
提高代码复用率,我们可以避免编写大量重复的代码。
2.2 pytest中的用例参数化
pytest是一个流行的Python测试框架。pytest中的标准用例参数化功能可以通过使用pytest.mark.parametrize装饰器来实现。下面是一个演示示例:
import pytest
@pytest.mark.parametrize("input1, input2, expected_output", [
("hello", "world", "helloworld"),
("foo", "bar", "foobar"),
("one", "two", "onetwo"),
])
def test_concatenation(input1, input2, expected_output):
assert input1 + input2 == expected_output
上述示例中,我们在 pytest.fixture下编写了一个名为“test_concatenation”的测试函数,然后在函数上应用了pytest.mark.parametrize装饰器。装饰器用于指定测试函数的输入参数(input1和input2)以及预期输出(expected_output) 的多个值-这是用例的不同值的组合,用于测试该函数。
3. 特殊的参数化案例temperature=0.6
接下来我们演示一下, 如何实现特殊的参数化案例 temperature=0.6。
假设我们有以下函数, 它的功能是将摄氏度转换为华氏度:
def celsius_to_fahrenheit(celsius):
if not isinstance(celsius, (int, float)):
raise TypeError("Celsius must be numerical")
return (celsius * 1.8) + 32;
根据华氏度和摄氏度之间的公式, 我们可以将摄氏度转换为华氏度:f = (c × 1.8)+32,其中f是华氏温度,c是摄氏温度。
我们现在想测试这个celsius_to_fahrenheit函数。我们有一个特殊的测试要求,即只有在温度为0.6摄氏度以下时,它才能正常工作。
我们可以使用Python中的doctest模块来实现这样的测试。我们在一个名为“testtemperaturerange”的测试函数中使用pytest.mark.parametrize装饰器。具体来说,我们将带有三个参数的单个元组作为 pytest.mark.parametrize装饰器的参数传递。第一个参数表示摄氏温度,第二个参数表示应该返回的华氏温度,第三个参数表示摄氏温度是否小于0.6。如果摄氏度小于0.6,则期望由测试断言引发ValueError,否则期望得到正确的华氏温度。
import pytest
from doctest import testmod
def celsius_to_fahrenheit(celsius):
if not isinstance(celsius, (int, float)):
raise TypeError("Celsius must be numerical")
return (celsius * 1.8) + 32
def testtemperaturerange():
for test in testcases:
celsius, fahrenheit, should_fail = test
if should_fail:
with pytest.raises(ValueError):
celsius_to_fahrenheit(celsius)
else:
assert round(celsius_to_fahrenheit(celsius),2) == fahrenheit
testcases = [
(-2,28.4,True),
(0.5,32.9,False),
(200, 392,False),
]
pytest.mark.parametrize("celsius,fahrenheit,should_fail",
[(case[0], case[1], case[2]) for case in testcases])
在上面的代码中,doctest.testmod()用于测试函数的文档字符串, 并在第一次失败后返回错误。如果有多个测试失败,则doctest.testmod()会抛出一个异常。这个异常会被pytest捕获,从而会展示出全部断言失败信息而不是停止在第一个断言失败。 通过运行我们的测试函数,我们可以测试出这个celsius_to_fahrenheit函数仅在摄氏度小于0.6时才能正常工作,否则会抛出ValueError。
4. 总结
在本文中,我们介绍了用例参数化的概念及其优势,重点讲解了pytest中的用例参数化。最后,我们演示了一个特殊的用例参数化案例temperature=0.6,通过这个案例,读者可以更深入地理解用例参数化的应用场景和价值。