Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pytest中参数笛卡尔积的参数化测试_Python_Pytest - Fatal编程技术网

Python pytest中参数笛卡尔积的参数化测试

Python pytest中参数笛卡尔积的参数化测试,python,pytest,Python,Pytest,只是想知道,有没有(更)优雅的笛卡尔积参数化方法?到目前为止,我发现: numbers = [1,2,3,4,5] vowels = ['a','e','i','o','u'] consonants = ['x','y','z'] cartesian = [elem for elem in itertools.product(*[numbers,vowels,consonants])] @pytest.fixture(params=cartesian) def somepara

只是想知道,有没有(更)优雅的笛卡尔积参数化方法?到目前为止,我发现:

numbers    = [1,2,3,4,5]
vowels     = ['a','e','i','o','u']
consonants = ['x','y','z']

cartesian = [elem for elem in itertools.product(*[numbers,vowels,consonants])]

@pytest.fixture(params=cartesian)
def someparams(request):
  return request.param

def test_something(someparams):
  pass

至少我想在fixture函数中封装数字、元音、辅音和笛卡尔。我可以想出两种方法。一个使用参数化夹具,一个参数化测试功能。这取决于你觉得哪一个更优雅

以下是参数化的测试功能:

import itertools
import pytest

numbers = [1,2,3,4,5]
vowels = ['a','e','i','o','u']
consonants = ['x','y','z']


@pytest.mark.parametrize('number,vowel,consonant',
    itertools.product(numbers, vowels, consonants)
)
def test(number, vowel, consonant):
    pass
值得注意的是,parametrize decorator的第二个参数可以是iterable,而不仅仅是list

以下是通过参数化每个装置来实现的方法:

import pytest

numbers = [1,2,3,4,5]
vowels = ['a','e','i','o','u']
consonants = ['x','y','z']


@pytest.fixture(params=numbers)
def number(request):
    return request.param

@pytest.fixture(params=vowels)
def vowel(request):
    return request.param

@pytest.fixture(params=consonants)
def consonant(request):
    return request.param


def test(number, vowel, consonant):
    pass
你的直觉是正确的。通过参数化多个装置中的每个装置,pytest负责创建所有出现的排列

测试输出是相同的。下面是一个示例(我使用-vv选项运行了py.test):


您可以应用多个
参数化
参数,在这种情况下,它们将生成所有参数的乘积:

import pytest

numbers = [1,2,3,4,5]
vowels = ['a','e','i','o','u']
consonants = ['x','y','z']


@pytest.mark.parametrize('number', numbers)
@pytest.mark.parametrize('vowel', vowels)
@pytest.mark.parametrize('consonant', consonants)
def test(number, vowel, consonant):
    pass

我认为除了一个优雅的解决方案之外,你还应该考虑每个选项所花费的时间和你必须维护的代码量。 可能的解决方案

  • 使用itertools(由Frank T提供)一次参数化
  • 使用3个固定装置(由Frank T提供)
  • 使用
    参数化
    3次(由Bruno Oliveira提供)
  • 使用1个夹具和itertools(问题中提供)
  • 解决方案1 解决方案2 解决方案3 解决方案4

    当谈到优雅时,我认为<强>解决方案3 <强>是最好的选择,因为它的代码维护较少,不需要导入代码>迭代器。在这之后,解决方案1是最佳选择,因为您不需要将fixture写为解决方案4,而解决方案2解决方案4可能优于解决方案2,因为它需要更少的代码来维护

    在性能方面,我使用
    numbers=list(范围(100))
    运行每个解决方案,并得到以下结果:

    |  Solution  |  Time    | 
    | Solution 1 |  3.91s   |
    | Solution 2 |  3.59s   |
    | Solution 3 |  3.54s   |
    | Solution 4 |  3.09s   |
    

    这在Python2中应该可以正常工作。你犯了什么错误?pytest 5.X不再支持Python2.7和Python3.4,但是那些执行“pip install pytest”的Python版本的用户将获得最后一个兼容版本4.6.X。
    @pytest.mark.parametrize('number, vowel, consonant',
                             itertools.product(numbers, vowels, consonants))
    def test(number, vowel, consonant):
        pass
    
    @pytest.fixture(params=numbers)
    def number(request): return request.param
    
    @pytest.fixture(params=vowels)
    def vowel(request): return request.param
    
    @pytest.fixture(params=consonants)
    def consonant(request): return request.param
    
    
    def test(number, vowel, consonant):
        pass
    
    @pytest.mark.parametrize('number', numbers)
    @pytest.mark.parametrize('vowel', vowels)
    @pytest.mark.parametrize('consonant', consonants)
    def test(number, vowel, consonant):
        pass
    
    @pytest.fixture(params=cartesian)
    def someparams(request):
      return request.param
    
    def test_something(someparams):
      pass
    
    |  Solution  |  Time    | 
    | Solution 1 |  3.91s   |
    | Solution 2 |  3.59s   |
    | Solution 3 |  3.54s   |
    | Solution 4 |  3.09s   |