Pytest inheritance and fixtures

86 Views Asked by At

I have a fixture that loads a yaml file, I have abase test class TestBaseA ans a sublass that inherites from it, TestB(TestBaseA ) In TestB i have the function test_values(): I want to paramtrize test_values() with the config values i got from the fixture. How do i do it? The code looks like this:

import pytest
import yaml
from 

@pytest.fixture(scope='session')
def load_config():
    with open(r"\test_plan_1.yaml") as f:
        data = yaml.safe_load(f)
    return data

class TestBase:

    def calculate_(self, test_path_1, test_path_2, window_size, threshold):
        
        return consecutive_failures

class TestB(TestBase):


    @pytest.mark.parametrize("threshold", //I want to read these values from the yaml loaded in the fixture)
    @pytest.mark.parametrize("window_size", //I want to read these values from the yaml loaded in the fixture)
    def test_resulty(self, threshold, window_size,load_config):
        try:

            consecutive_failures = self.calculate_
            )
            assert consecutive_failures == 0
1

There are 1 best solutions below

0
VonC On

You could follow what is described in How to parametrize fixtures and test functions

You cannot directly use a fixture to parametrize a test function with @pytest.mark.parametrize since it is designed for static values. But you can achieve a similar effect by using the pytest_generate_tests hook to dynamically parametrize your test based on the contents of the YAML file.

Instead of directly using the fixture to pass parameters to your test, you will load your YAML configuration in a session-scoped fixture (i.e. the fixture is destroyed at the end of the test session.), or directly within the pytest_generate_tests hook if the configuration is solely used for parametrization and not needed in the test body.

Implement the pytest_generate_tests hook in your conftest.py or test module to read the YAML data and use it to dynamically generate tests with the desired parameters:

# conftest.py or within your test module
import pytest
import yaml

def pytest_generate_tests(metafunc):
    if 'threshold' in metafunc.fixturenames or 'window_size' in metafunc.fixturenames:
        with open(r"\test_plan_1.yaml") as f:
            data = yaml.safe_load(f)
        # Assuming your YAML file structure allows direct extraction of values for parametrization
        thresholds = data['thresholds']
        window_sizes = data['window_sizes']
        if 'threshold' in metafunc.fixturenames:
            metafunc.parametrize('threshold', thresholds)
        if 'window_size' in metafunc.fixturenames:
            metafunc.parametrize('window_size', window_sizes)

# Your test module
class TestB(TestBase):

    def test_resulty(self, threshold, window_size):
        # Your test implementation

The pytest_generate_tests hook reads your YAML configuration and dynamically applies parametrization to your tests based on the contents.

In detail:

pytest_generate_tests is a hook function that pytest calls when collecting a test function. That happens before any test is actually executed.
During the test collection phase, pytest identifies all the test functions and classes in the specified directories and files. For each collected test function, pytest checks if there is a pytest_generate_tests function defined in the conftest.py files or directly in the test modules.
If pytest_generate_tests is found, pytest invokes it, passing a metafunc object as the argument. That metafunc object contains metadata about the test function including its name, the fixture names it uses, and a method to parametrize the test function (metafunc.parametrize()).
Inside pytest_generate_tests, you can use metafunc.parametrize() to dynamically generate parameters for the test functions based on your custom logic. You can access the command-line arguments, read files, or generate data programmatically to decide the parameters.