简体   繁体   中英

How can I loop over the @pytest.mark.parametrize data or print it on the tests

I have this data that basically are parameters that i want to pass into a function:

data2 = { "user": "bender", "resource": "machine/2", "action": "delete"}
data3 = { "user": "bender", "resource": "machine/2", "action": "delete"}
data4 = { "user": "bender", "resource": "machines/*", "action": "*"}
data5 = { "user": "leela", "resource": "machine/1", "action": "delete"}
data6 = { "user": "leela", "resource": "machine/*", "action": "*"}

I have this test using @pytest.mark.parametrize :

@pytest.mark.parametrize("test_input",  [
    data2,
    data3,
    data4,
    data5,
    data6,
])
@patch("dev_maintenance.roles.db")
def test_check_if_user_has_permissions(db,test_input):
    tmp = {}
    tmp["user"] = "bender"
    tmp["resource"] = "machine/1"
    tmp["action"] = "delete"

    db.session.query.return_value.filter_by.return_value.join.return_value.all.return_value = [(tmp["user"], tmp["resource"], tmp["action"])]

    assert check_if_user_has_permissions(user = "bender",resource= "machine/1", access_token= "delete") == True

What I want to achieve is pass each data set on the check_if_user_has_permissions(user, resource, action) so I can assert is value, and if the assert fails because the assertion was True == False I want that test case to pass, because in my scenario if this happens it means that the user has no permissions, and the test should pass.

I was trying to print on the tests like print(test_input) to see if it would print all data sets but in only prints one.

It seems like you're asking two separate questions. If you want to assert a negative just use assert not . If you run pytest with the -v flag it will output all the tests it's running, and for parametrized tests it will also show each parameter value it's running the test with.

You can write your test sort of like this:

$ cat test.py
import pytest

data = [
    { "user": "bender", "resource": "machine/2", "action": "delete"},
    { "user": "bender", "resource": "machine/2", "action": "delete"},
    { "user": "bender", "resource": "machines/*", "action": "*"},
    { "user": "leela", "resource": "machine/1", "action": "delete"},
    { "user": "leela", "resource": "machine/*", "action": "*"}
]


def check_if_user_has_permissions(*args, **kwargs):
    # Dummy implementation for demonstration
    import random
    print(kwargs)
    return random.choice([True, False])


@pytest.mark.parametrize('test_input', data)
def test_check_if_user_has_permissions(test_input):
    # ... additional test setup ...
    assert not check_if_user_has_permissions(**test_input)

Then run:

$ pytest -v test.py
============================= test session starts ==============================
platform cygwin -- Python 3.6.8, pytest-5.3.1, py-1.8.0, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: .
collected 5 items

test.py::test_check_if_user_has_permissions[test_input0] PASSED          [ 20%]
test.py::test_check_if_user_has_permissions[test_input1] PASSED          [ 40%]
test.py::test_check_if_user_has_permissions[test_input2] PASSED          [ 60%]
test.py::test_check_if_user_has_permissions[test_input3] FAILED          [ 80%]
test.py::test_check_if_user_has_permissions[test_input4] FAILED          [100%]

=================================== FAILURES ===================================
_______________ test_check_if_user_has_permissions[test_input3] ________________

test_input = {'action': 'delete', 'resource': 'machine/1', 'user': 'leela'}

    @pytest.mark.parametrize('test_input', data)
    def test_check_if_user_has_permissions(test_input):
>       assert not check_if_user_has_permissions(**test_input)
E       AssertionError: assert not True
E        +  where True = check_if_user_has_permissions(**{'action': 'delete', 'resource': 'machine/1', 'user': 'leela'})

test.py:21: AssertionError
----------------------------- Captured stdout call -----------------------------
{'user': 'leela', 'resource': 'machine/1', 'action': 'delete'}
_______________ test_check_if_user_has_permissions[test_input4] ________________

test_input = {'action': '*', 'resource': 'machine/*', 'user': 'leela'}

    @pytest.mark.parametrize('test_input', data)
    def test_check_if_user_has_permissions(test_input):
>       assert not check_if_user_has_permissions(**test_input)
E       AssertionError: assert not True
E        +  where True = check_if_user_has_permissions(**{'action': '*', 'resource': 'machine/*', 'user': 'leela'})

test.py:21: AssertionError
----------------------------- Captured stdout call -----------------------------
{'user': 'leela', 'resource': 'machine/*', 'action': '*'}
========================= 2 failed, 3 passed in 0.19s ==========================

I found an easier solution to this problem after some time.

I did a mark.parametrize like this:

data = 
[
["bender", "machine_4", "action1", False],
["leela", "machine_2", "action1", False],
["leela", "file/2", "action4", True],
["leela", "file/2", "action2", False],
["leela", "application/1", "action1", True],
["leela", "application/2", "action1", False],
["fry", "application/1", "action1", True],
["zoidberg", "application/1", "action1", False],
]


@pytest.mark.parametrize("user,resource,action, expected", data)
@patch("dev_maintenance.roles.db")
def test_check_if_user_has_permissions(db,user,resource,action,expected):

    db.session.query.return_value.filter_by.return_value.join.return_value.all.return_value = \
        [
            ("bender", "machine_1", "action1"),
            ("bender", "machine_2", "action1"),
            ("bender", "machine_3", "action1"),
            ("bender", "machine_3", "action2"),
            ("leela", "file/*", "action4"),
            ("leela", "application/1", "*"),
            ("fry", "*", "*"),
        ]

    assert check_if_user_has_permissions(user, resource, action) == expected

What i did here was passing the user , resource and action parameters to the function and assert that the response of the function with those parameters is equal to the expected parameter. So it will work like True == True, depending on the parameters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM