Search code examples
pythonpython-3.xparameterspytestfixtures

Execute select combinations and prevent pytest from running all parameterise combinations


There are 3 users and 5 codes

@pytest.mark.fns
@pytest.mark.parametrize("USER, PWD", [(user1, user1pwd), (user2, user2pwd), (user3, user3pwd)])
@pytest.mark.parametrize("CODE", ['code1', 'code2', 'code3', 'code 4', 'code 5'])

def fn1(CODE, USER, PWD):
    ...
    ...
    do something
    ...
    ...

Right now, if I run pytest -m "fns", the function fn1 will run 15 times with all CODE and USER, PWD combinations. However I only want it to run 5 times like the following:

fn1(code1, user1, user1pwd)
fn1(code2, user2, user2pwd)
fn1(code3, user3, user3pwd)
fn1(code4, user1, user1pwd)
fn1(code5, user2, user2pwd)

That is, code 1,2 and 3 be passed with user1,2 and 3 and then the remaining code 4 and 5 be passed with user1 and 2.

Edit1: The number of codes can vary from 1 to 1000s whereas there are only 3 users. And each code needs to be passed only once with only 1 user.

I went through fixtures but its too difficult for me to understand. Can someone explain me how I can accomplish this?


Solution

  • import itertools
    
    def fn1_parameters():
        for code, (user, pwd) in zip(
            ["code1", "code2", "code3", "code4", "code5"],
            itertools.cycle([
                ("user1", "user1pwd"),
                ("user2", "user2pwd"),
                ("user3", "user3pwd"),
            ])
        ):
            yield code, user, pwd
    

    Then either:

    def test_fn1():
        for code, user, pwd in fn1_parameters():
            fn1(code, user, pwd)
    

    or

    # Not sure if list() is needed
    @pytest.mark.parametrize("code", "user", "pwd", list(fn1_parameters()))
    def fn1(code, user, pwd):