parameterized test with cartesian product of arguments in pytest

前端 未结 3 442
迷失自我
迷失自我 2020-12-24 06:09

Just wondering, is there any (more) elegant way of parameterizing with the cartesian product? This is what I figured out so far:

numbers    = [1,2,3,4,5]
vow         


        
3条回答
  •  一生所求
    2020-12-24 06:31

    I can think of two ways to do this. One uses parametrized fixtures, and one parametrizes the test function. It's up to you which one you find more elegant.

    Here is the test function parametrized:

    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
    

    Of note, the second argument to the parametrize decorator can be an iterable, not just a list.

    Here is how you do it by parametrizing each fixture:

    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
    

    Your intuition was correct. By parametrizing each of multiple fixtures, pytest takes care of creating all the permutations that arise.

    The test output is identical. Here is a sample (I ran py.test with the -vv option):

    test_bar.py:22: test[1-a-x] PASSED
    test_bar.py:22: test[1-a-y] PASSED
    test_bar.py:22: test[1-a-z] PASSED
    test_bar.py:22: test[1-e-x] PASSED
    test_bar.py:22: test[1-e-y] PASSED
    test_bar.py:22: test[1-e-z] PASSED
    test_bar.py:22: test[1-i-x] PASSED
    

提交回复
热议问题