question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

how to get data from fixture to parametrize with @parametrize ? (with repository example)

See original GitHub issue

I created this repository to demonstrate the problem

https://github.com/andreabisello/pytest-fixture-as-parameter

there are a fixture and three test.

import pytest
import requests

@pytest.mark.parametrize('endpoint', [
    "https://www.google.it",
    "https://www.google.com"
])
def test_parametrized(endpoint):
    """
    this will create two tests, one for every value of the endpoint parameter
    """
    print("checking : " + endpoint)
    assert requests.get(endpoint).status_code == 200

@pytest.fixture(scope="session")
def get_endpoints():
    return [
        "https://www.google.it",
        "https://www.google.com"
    ]

def test_using_fixture(get_endpoints):
    """this will assert the result of the fixture"""
    assert get_endpoints == [
        "https://www.google.it",
        "https://www.google.com"
    ]

@pytest.mark.parametrize('endpoint', get_endpoints)
def test_parametrizing_using_fixture(endpoint):
    """
    this should load data from get_endpoints fixture and pass every value of 
    get_endpoints as endpoint value
    """
    print("checking : " + endpoint)
    assert requests.get(endpoint).status_code == 200

a test is using @mark.parametrize and it works.

a test is using the fixture and it works.

a test is trying to use the fixture as values for the @mark.parametrize and it cannot works.

but i would like to load the @mark.parametrize values from a fixture.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:4
  • Comments:17 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
andreabisellocommented, Dec 30, 2019

@JoshKarpel @Zac-HD my need is a little different. thanks for your help.

the problem is related to the fact i cannot hardcode

params = [
    "https://www.google.it",
    "https://www.google.com"
])

because this needs to be returned by a fixture,

i give you the context.

my testsuite needs to be executed in 4 different environments ( staging , quality, pre production , production ) and the configuration for every environment is stored in a json file . due some environments share some configuration values, configuration file is splitted in several files : one with username and passwords, one with assets links, one with endpoints and so on. when i need to change environment, i change files and i re run the suite.

now, i want to parametrize the choose of the file on the pytest command line.

to obtain this is used pytest_addoption(parser) in conftest.py like this

def pytest_addoption(parser):
    parser.addoption("--users", action="store", default="test", help="file contenente username e password. senza .json")
    parser.addoption("--endpoints", action="store", default="integration")
    parser.addoption("--assets", action="store", default="test")
    parser.addoption("--environment", action="store", default="test")

i permit to choose what file to load, and fixtures load the configuration from the file e.g.

@pytest.fixture(scope="session")
def users(request):
    users = None
    users = request.config.getoption("--users")

    with open('configurations/users-'+users+'.json', 'r') as f:
        users = json.load(f)
    return users

and this works, every test class have a fixture with autouse used to load required parameters from the loaded json files

class TestServizi():

    @pytest.fixture(autouse=True)
    def init(self, users, endpoints, assets, environment):

        self.username = users['userServizi']
        self.password = bytes(users['passwordUserServizi'],"utf-8")
        self.client = Client(endpoints["solutionUpdate"])

i use the autouse fixture to avoid loading fixture in every single test, due the test class use everytime the same parameter.

it works good.

one of the test, check if every of the 11 endpoints returns http status 200 ok.

sure, i can create 11 tests, or i can create a test looping to the array of 11 endpoints, but i would like to use parametrize to create 11 tests.

and this is my initial approach

def test_using_fixture(get_endpoints):
    """this will assert the result of the fixture"""
    assert get_endpoints == [
        "https://www.google.it",
        "https://www.google.com"
    ]

@pytest.mark.parametrize('endpoint', get_endpoints)
def test_parametrizing_using_fixture(endpoint):
    """
    this should load data from get_endpoints fixture and pass every value of 
    get_endpoints as endpoint value
    """
    print("checking : " + endpoint)
    assert requests.get(endpoint).status_code == 200

but you teached me to use this snipped

@pytest.fixture(scope = "session", params = [
    "https://www.google.it",
    "https://www.google.com"
])
def endpoint(request):
    return request.param


def test_parametrizing_using_fixture(endpoint):
    print("checking : " + endpoint)
    assert requests.get(endpoint).status_code == 200

the problem is related to the fact i cannot hardcode

params = [
    "https://www.google.it",
    "https://www.google.com"
])

because this needs to be returned by the fixture.

so i tried something like this

@pytest.fixture(scope="session", params = endpoints['provisioning'])
def provisioning_endpoint(request):
    return request.param

where endpoints is a fixture that return a dictionary and provisioning in a keys of this dictionary containing the array of the url i need to check

def test_endpoints_from_fixture(provisioning_endpoint):
    print(provisioning_endpoint)

but i obtain this error loading the conftest.py

TypeError: 'function' object is not subscriptable
2reactions
JoshKarpelcommented, Dec 28, 2019

A parametrized fixture indirectly parametrizes all of the fixtures/tests that depend on it, without needing to explicitly use @parametrize on the tests:

import pytest
import requests


@pytest.fixture(scope = "session", params = [
    "https://www.google.it",
    "https://www.google.com"
])
def endpoint(request):
    return request.param


def test_parametrizing_using_fixture(endpoint):
    print("checking : " + endpoint)
    assert requests.get(endpoint).status_code == 200

Running pytest -v to see what tests are generated:

$ pytest -v
===== test session starts =====
platform linux -- Python 3.7.5, pytest-5.3.2, py-1.8.0, pluggy-0.13.1 -- 
cachedir: .pytest_cache
rootdir: 
collected 2 items

test_req.py::test_parametrizing_using_fixture[https://www.google.it] PASSED  
test_req.py::test_parametrizing_using_fixture[https://www.google.com] PASSED  

===== 2 passed in 0.91s =====

If this isn’t what you want, could you provide an example that’s closer to your real code?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Pytest: How to use fixtures as arguments in parametrize
The request fixture has a method called getfixturevalue . This method allows you to request the value of a fixture by its name....
Read more >
pytest using fixtures as arguments in parametrize
Another way is to use lazy-fixture plugin: @pytest.mark.parametrize('dirname, expected', ... Example: @pytest.fixture(scope="class", ...
Read more >
Parametrizing fixtures and test functions — pytest documentation
pytest.fixture() allows one to parametrize fixture functions. ... Here is a typical example of a test function that implements checking that a certain...
Read more >
Python parametrized testing - The Blue Book
Fixtures may have parameters. Those parameters are passed as a list to the argument params of @pytest.fixture() decorator. Those parameters must be iterables, ......
Read more >
How To Do Parameterization In Pytest With Selenium?
In this Selenium Python tutorial, we will see how pytest.fixture, @pytest.mark.parametrize decorator and pytest_generate_tests() can be used ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found