как правильно выполнить pytest функцию с тем же кодом, который использовался для заполнения параметра области модуля

#python #pandas #pytest

#python #pandas #pytest

Вопрос:

У меня есть созданное мной приспособление, которое извлекает данные из базы данных и помещает их в DataFrame, чтобы все последующие тесты могли выполняться с одним и тем же выводом запроса. Тот же код размещен в функции, которая запускает мой конвейер обработки данных (вокруг которого я строю все эти тесты). Я не уверен, что хочу имитировать результат запроса БД, потому что я хочу проверить возвращаемые имена столбцов из запроса и записать уникальность среди прочего.

Где я в замешательстве, так это как правильно протестировать функцию, которую я имею в своем коде, которая выполняет то же самое, output_data что и прибор. Правильно ли дублировать код в моем приложении для приспособления?

 # df_service.py
from project.settings import MSSQL_DB_CON_STR as con

def df_from_sql(start_date, months):     
    sql = f"SELECT * FROM dbo.awesome_table_value_function('{start_date}', {months})"    
    return pd.read_sql(sql=sql, con=con)    
  

Вот приспособление, с которого я начал, прежде чем понял, что создаю приспособление для функциональности, которую я действительно хочу протестировать и использовать в качестве приспособления.

 # test_df_service.py

import pytest
import pandas as pd

@pytest.fixture(scope="module")
def output_data():
    from project.settings import MSSQL_DB_CON_STR as con

    start_date = "11/1/2019"
    months = 4
    sql = f"SELECT * FROM dbo.awesome_table_value_function('{start_date}', {months})"    
    return pd.read_sql(sql=sql, con=con)   

    return pd.read_sql(sql=sql, con=con)

def test_columns(output_data):
    expected_columns = ['entity','attribute','value','effective_date']
    df = output_data
    for col in df.columns:
        assert col in expected_columns 

  

Ответ №1:

Итак, один из способов, которым вы могли бы это сделать, заключается в следующем:

Поскольку df_from_sql() функция находится в домене вашего приложения, она также должна быть функцией, которую вы действительно хотите протестировать. Итак, я бы написал тест pytest для функции, утверждая такие вещи, как Does it return X number of columns или Is the number of rows > 0 и т. Д. (Если вы не можете гарантировать возврат одних и тех же данных каждый раз).

Я понимаю, почему вы хотели бы использовать функцию для создания прибора, однако это создает следующие риски:

  • Функция для получения данных по какой-то причине не работает. Тогда все ваши тесты могут завершиться неудачей, потому что ваши ouput data тесты не соответствуют их ожиданиям.
  • Данные в базе данных могут измениться, поэтому вы получите результаты, отличные от ожидаемых.

Теоретически, приспособления должны быть как можно более фиксированными в пространстве и времени, поэтому я бы рекомендовал сохранить нужные вам данные в качестве output_data приспособления в каком-либо файле или, возможно, в макетной таблице в вашей базе данных, гарантируя, что они никогда не изменятся.

Комментарии:

1. Я правильно понимаю вас с моей суммой? 1) Протестируйте df_from_sql функцию, указав такие вещи, как столбцы, которые она возвращает 2) В отдельных тестах, которые работают с df_from_sql результатом, используйте статические данные в приборе.

2. Это то, что я имел в виду, да