es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

pytest: use el fixture con el dataframe de pandas para la parametrización.

Tengo una fixture que devuelve un pd.DataFrame. Necesito insertar las columnas individuales (pd.Series) en una prueba unitaria y me gustaría usar parametrize.

Aquí hay un ejemplo sencillo sin parametrize. Cada columna del dataframe se prueba individualmente. Sin embargo, supongo que puedo deshacerme de la fixture input_series, ¿no? Con este código, solo se ejecutará una prueba. Sin embargo, estoy buscando realizar 3 pruebas al mismo tiempo que elimino el bucle for.

import numpy as np
import pandas as pd
import pytest


@pytest.fixture(scope="module")
def input_df():
    return pd.DataFrame(
        data=np.random.randint(1, 10, (5, 3)), columns=["col1", "col2", "col3"]
    )


@pytest.fixture(scope="module")
def input_series(input_df):
    return [input_df[series] for series in input_df.columns]


def test_individual_column(input_series):
    for series in input_series:
        assert len(series) == 5

Básicamente, estoy buscando algo como esto:

@pytest.mark.parametrize("series", individual_series_from_input_df)
def test_individual_column(series):
    assert len(series) == 5
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para parametrizar las columnas individuales del objeto input_df, podemos modificar el objeto input_series para que devuelva un diccionario de pd.Series, con las llaves siendo los nombres de las columnas. Luego, podemos utilizar el método items() del diccionario para pasar cada serie individual como parámetro a la función test_individual_column. Aquí está el código modificado:

    import numpy as np
    import pandas as pd
    import pytest
    
    
    @pytest.fixture(scope="module")
    def input_df():
        return pd.DataFrame(
            data=np.random.randint(1, 10, (5, 3)), columns=["col1", "col2", "col3"]
        )
    
    
    @pytest.fixture(scope="module")
    def input_series(input_df):
        return {col_name: input_df[col_name] for col_name in input_df.columns}
    
    
    @pytest.mark.parametrize("series_name, series", input_series.items())
    def test_individual_column(series_name, series):
        assert len(series) == 5
    

    En este código modificado, primero definimos el objeto input_df como antes. El objeto input_series ahora devuelve un diccionario de pd.Series, con las llaves siendo los nombres de las columnas. Utilizamos una comprensión de diccionario para crear este diccionario, iterando sobre los nombres de las columnas del objeto input_df y obteniendo la correspondiente pd.Series para cada columna.

    En la función test_individual_column, utilizamos el decorador @pytest.mark.parametrize para parametrizar la función con dos argumentos: series_name y series. Estos corresponden a los pares clave-valor del diccionario input_series. Pasamos el método items() del diccionario a @pytest.mark.parametrize() para desempaquetar cada par clave-valor como argumentos separados.

    Con estas modificaciones, la función test_individual_column se llamará una vez por cada columna del objeto input_df, con los parámetros series_name y series tomando los valores del nombre de columna actual y pd.Series, respectivamente. La instrucción assert verifica que la longitud de cada pd.Series sea igual a 5.

Comments are closed.