Python para el probador: cómo los pequeños scripts de c pandas ayudan a probar grandes conjuntos de datos

Trabajo como probador en un proyecto, cuya esencia es la recopilación y el almacenamiento de diversos datos y la formación de diversos informes y cargas de archivos sobre la base de ellos. Al generar dichos informes, se tienen en cuenta una gran cantidad de condiciones para la selección de datos y, por lo tanto, al realizar las pruebas, debe trabajar mucho con las consultas SQL en la base de datos. Pero para verificar la selección correcta de datos y buscar datos en exceso / faltantes, esto a menudo no es suficiente, así que tuve que buscar herramientas adicionales para esto.

Como ya tenía algunos conocimientos básicos de Python, decidí intentar escribir pequeños scripts que me permitieran hacer algo con los datos existentes y así facilitar y acelerar el proceso de prueba. En este artículo te diré lo que salió de él.

Diseñar un guión guión


Para escribir una secuencia de comandos, debe averiguar qué debe hacer exactamente la secuencia de comandos, qué datos deben ingresarse y qué datos se espera que salgan.

Pasos de muestra para el escenario:

  1. Obtenemos un archivo con datos en cierto formato (o varios archivos)
  2. Obtener datos de archivo / archivos
  3. Seleccionamos los datos necesarios.
  4. Realizamos algunas operaciones sobre datos
  5. Cargamos datos a un archivo de Excel, si es necesario (generalmente este formato es el más conveniente para su posterior análisis y almacenamiento)

Luego debe pensar cómo y dónde puede obtener información. Puede ser un archivo creado manualmente con datos, cargando datos a una interfaz de usuario en un archivo con filtros, un archivo con análisis de datos utilizando otro script, un archivo para cargar los resultados de una consulta SQL a la base de datos (puede cargar rápidamente datos a un archivo csv desde la base de datos), json -archivo o archivo xml con datos de la respuesta a una solicitud a la API, etc.

Escribimos scripts en python usando pandas y otras bibliotecas.


Para escribir scripts en python, necesita instalar un intérprete y un IDE adecuado. También es mejor crear un entorno virtual separado para este proyecto.

Utilizo diferentes bibliotecas para scripts, algunas de ellas son bibliotecas de python integradas , algunas necesitan instalarse adicionalmente:

  • pandas es una biblioteca para el análisis de datos. Le permite trabajar con datos de archivos de varios formatos, así como recibir datos directamente de la base de datos mediante una consulta SQL. Los datos de los archivos se cargan en marcos de datos (visualmente las mismas tablas que en Excel), con datos en los que ya puede realizar diferentes operaciones: combine datos de diferentes marcos de datos por analogía con join / union en SQL, seleccione los datos que necesita bajo ciertas condiciones, compare datos en diferentes columnas del marco de datos, etc.
  • openpyxl, xlrd : bibliotecas para trabajar con Excel.

El marco de script más simple para trabajar con datos de archivos csv, json, Excel es el siguiente:

#   pandas
import pandas as pd

#    csv-  -
# (        )
#       csv-     ";"
df = pd.read_csv('./csv_file.csv', sep=';', encoding='utf-8')

# 
#    json-  -
# (        )
# df = pd.read_json('./json_file.json', encoding='utf-8')

# 
#    Excel-  -,     
# (        )
# file_excel = 'Excel_file.xlsx'
# df = pd.ExcelFile(file_excel).parse('1')


#  -     -  
#    - final_df


#    Excel-,  
#          
# (      )
writer = pd.ExcelWriter('.xlsx')
final_df.to_excel(writer, '1')
writer.save()

En este script, los datos de un archivo del formato requerido se cargan en un marco de datos, se seleccionan los datos necesarios y se realizan algunas operaciones en ellos, luego los datos se escriben en un nuevo archivo de Excel.

Si necesita trabajar con datos obtenidos como resultado de una consulta SQL a la base de datos, no puede exportarlos a un archivo csv, sino que inmediatamente los lleva a un marco de datos ejecutando una consulta SQL en la base de datos en el script mismo:

#   pandas
import pandas as pd
#      ,     PostgreSQL
# (   -    )
import psycopg2

#    
conn = psycopg2.connect(dbname='_', host='', port='',
                        user='', password='')

#   SQL-
q = """select ... 
    from ... 
    where ..."""

#    -,  SQL-
df = pd.read_sql_query(q, conn)


#  -     -  
#    - final_df


#    Excel-,  
#          
# (      )
writer = pd.ExcelWriter('.xlsx')
final_df.to_excel(writer, '1')
writer.save()

Si necesita obtener datos de un archivo xml, puede usar las bibliotecas diseñadas para esto. Yo uso la biblioteca incorporada ElementTree .

Cuando los datos se reciben en un marco de datos, puede combinarlos inmediatamente con datos de otro marco de datos (análogos de unión o unión en SQL) o realizar algunas operaciones en ellos, por ejemplo, eliminar duplicados, eliminar filas con valores vacíos en ciertas celdas , compare datos en varias columnas, seleccione las filas / columnas deseadas, etc. Lea más en la documentación para pandas.

Opciones de uso de script


Y ahora activamos la herramienta principal del probador y seleccionamos los datos / características de nuestro proyecto, para verificar qué scripts serían útiles.

Se crearon archivos con una pequeña cantidad de datos de prueba generados utilizando generatedata para los scripts . En realidad, los archivos de datos contienen decenas de miles de filas y una gran cantidad de columnas.

Escenario # 1

Hay tres archivos en formato csv con datos. Para cada línea de datos, hay un campo con un identificador de identificación único. Los datos de estos archivos se seleccionan teniendo en cuenta ciertas condiciones y se ingresan en una tabla en la base de datos, luego estos datos se muestran en un informe en forma de una tabla en la interfaz de usuario. Es posible cargar datos en una interfaz de usuario a un archivo de Excel.

Suponga que las condiciones para seleccionar datos para un informe de los archivos de origen son las siguientes:

  • Los archivos pueden tener duplicados por identificación, en un informe, un registro con el mismo identificador debe tenerse en cuenta solo una vez (en este caso, simplemente seleccionamos cualquiera de las filas con este identificador de los datos).
  • Las filas con datos faltantes en la celda de la columna reg_date no deben contarse.
  • De hecho, puede haber más condiciones de selección, los datos también se pueden comparar con los datos que ya están en el sistema y solo se mostrarán en el informe los datos que se cruzan por identificación, pero por ejemplo tendremos en cuenta solo las dos condiciones indicadas anteriormente.

La tarea del probador: Compruebe que las líneas con los objetos necesarios se seleccionan correctamente de los archivos de origen y que todos estos objetos se muestran en el informe en la interfaz de usuario.

Redactamos un guión para el guión:

  • - csv-, - ( union SQL), id, reg_date.
  • UI Excel-, , -.
  • (merge) - ( outer join SQL) Excel- .
  • , , - , , UI.

En el archivo final, los datos contendrán solo una columna con id, si los nombres de las columnas en diferentes marcos de datos coinciden, y puede que no esté claro qué columnas / filas de qué archivo se encontraban. Por lo tanto, nombro las columnas con un identificador único por diferentes nombres en los archivos, o agrego una columna separada "Filas de un archivo de tal o cual" a cada archivo y pongo "Sí" en él; luego, al analizar el archivo Excel resultante, es conveniente filtrar por esta columna porque siempre contienen un valor y, al filtrar por ellos, ya puede comprender qué datos divergen en las columnas correspondientes.

Datos de ejemplo del archivo example1_csv_1.csv :



Datos de ejemplo del archivo report_UI.xlsx : Un



script de Python se ve así:

#   pandas
import pandas as pd

#     csv-    -
# (        )
df_from_file1 = pd.read_csv('./example1_csv_1.csv', sep=';', encoding='utf-8',
                            usecols=['id', 'name', 'email', 'reg_date'])
df_from_file2 = pd.read_csv('./example1_csv_2.csv', sep=';', encoding='utf-8',
                            usecols=['id', 'name', 'email','reg_date'])
df_from_file3 = pd.read_csv('./example1_csv_3.csv', sep=';', encoding='utf-8',
                            usecols=['id', 'name', 'email', 'reg_date'])

#    -    - 
# (   union  SQL)
df_from_csv = pd.concat([df_from_file1, df_from_file2, df_from_file3]).\
    reset_index(drop=True)
print(df_from_csv)

#       
df_from_csv.drop_duplicates(subset='id', keep='first', inplace=True)
print(df_from_csv)

#     NaN ( )   reg_date
df_from_csv = df_from_csv.dropna()
print(df_from_csv)

#    Excel-   UI  -,
#       
# (        )
file_excel = 'report_UI.xlsx'
df_from_excel = pd.ExcelFile(file_excel).parse('1')
print(df_from_excel)

#  -     - 
# -       UI
# (   outer join  SQL)
df = df_from_csv.merge(df_from_excel, left_on='id', right_on="", how='outer')
print(df)

#     Excel-
writer = pd.ExcelWriter('.xlsx')
df.to_excel(writer, '1')
writer.save()

Limitaciones:

  • ( , 30 000 ).
  • ( Excel) / , .

Escenario No. 2
La sección contiene datos en forma de tabla para ciertos objetos de una sola fuente. El sistema recibirá datos de una segunda fuente (integración) y actualizará los datos de la tabla existente con estos datos. Cada registro en la tabla son datos para un objeto que tiene un identificador único. Si desde una nueva fuente los datos de un objeto por identificador coinciden con los datos de un objeto existente, entonces todos los campos de un registro existente se actualizan con datos de una nueva fuente (confirmado). Si la tabla aún no tiene un objeto con un identificador de la segunda fuente, se crea un nuevo registro en la tabla con datos de la nueva fuente. Los datos del segundo sistema se pueden cargar en un archivo json de antemano.

La tarea del probador:Prepare un archivo con datos para la prueba de antemano, a fin de verificar que los registros existentes se actualicen correctamente y se fijen con un signo de confirmación en la base de datos si hay una coincidencia por identificador, y los nuevos registros se crean correctamente y se marcan con el signo de agregar a la base de datos si los registros con tales el identificador aún no estaba.

Redactamos un guión para el guión:

  • Cargamos los datos de la tabla de particiones al archivo de Excel en la interfaz de usuario (si esto no es posible, siempre puede exportar los datos del resultado de la consulta SQL utilizada en el código para enviar datos a esta tabla en la interfaz de usuario) y rellenar los datos desde el primer marco de datos .
  • Obtenemos el archivo json con datos de la segunda fuente y lo cargamos en el segundo marco de datos.
  • (merge — outer join SQL) - - Excel-, . , , .

:

  • ( , 30 000 ).
  • json- / – /, - json- pandas /.

Escenario 3

Se realiza una solicitud a la API del sistema, en respuesta a la cual se reciben datos sobre objetos en formato json.

Tarea del probador: compare los datos de la respuesta a la solicitud a la API con los datos del resultado de la consulta SQL en la base de datos.

Redactamos un guión para el guión:

  • Ejecutamos la consulta SQL en la base de datos, exportamos los datos del resultado de la consulta a un archivo csv, cargamos estos datos en el primer marco de datos.
  • Guardamos los datos de la respuesta a la solicitud a la API en el archivo json, cargamos los datos del archivo en el segundo marco de datos.
  • Combinamos los datos (fusión, por analogía con la unión externa en SQL) de dos marcos de datos recibidos en un nuevo marco de datos mediante un identificador único y descargamos los datos de este en un archivo Excel, en el que ya compararemos los datos por columnas utilizando las funciones de Sobresalir
  • O los datos en las columnas en el marco de datos generales se pueden comparar usando pandas, mientras se descargan las filas con los mismos / diferentes datos en las columnas en un nuevo marco de datos / archivo Excel para su análisis.

Datos de ejemplo del archivo example3_csv.csv :



Datos de ejemplo del archivo example3_json.json :

[
    {
        "id": "16421118-4116",
        "name_json": "Tempor Consulting",
        "email_json": "Nullam.lobortis.quam@***",
        "tel_json": "1-821-805-****",
        "reg_date_json": "12-11-16",
        "city_json": "Natales"
    },
    {
        "id": "16040210-2206",
        "name_json": "Odio Etiam Incorporated",
        "email_json": "arcu@***",
        "tel_json": "1-730-291-****",
        "reg_date_json": "26-06-05",
        "city_json": "Viddalba"
    },
...
]

El script de Python se ve así:

#   pandas
import pandas as pd

#    csv-  -
# (        )
#       csv-     ";"
df_from_csv = pd.read_csv('./example3_csv.csv', sep=';', encoding='utf-8')
print(df_from_csv)

#    json-  -
# (        )
df_from_json = pd.read_json('./example3_json.json', encoding='utf-8')
print(df_from_json)

#  -    -
# (   outer join  SQL)
df_csv_json = df_from_csv.merge(df_from_json, left_on='id', 
                                right_on="id", how='outer')
print(df_csv_json)

#    Excel-,   ,
#      -   ,
#          
# (      )
# writer = pd.ExcelWriter('.xlsx')
# df_csv_json.to_excel(writer, '1')
# writer.save()

#       
# (, name_csv  name_json) 
#       Excel-  
# (        )
unequal_data_df = df_csv_json.loc[df_csv_json['name_csv'] != 
                                  df_csv_json['name_json']]
unequal_data_df = unequal_data_df[['id', 'name_csv', 'name_json']]
print(unequal_data_df)

writer = pd.ExcelWriter('_name.xlsx')
unequal_data_df.to_excel(writer, '1')
writer.save()


Limitaciones:

  • Cuando trabaje con archivos con una gran cantidad de líneas, tendrá que dividirlos en archivos separados (aquí debe intentarlo, rara vez tengo archivos de más de 30,000 líneas).
  • Si hay varios niveles de anidamiento de objetos / matrices de datos en el archivo json, desde los niveles internos se cargarán en la celda como un objeto / matriz, por lo tanto, trabajar con archivos json con pandas es conveniente solo para datos sin anidamiento excesivo de objetos / arrays.
  • API SQL- , SQL- .

Si la respuesta a la solicitud a la API viene en formato xml, primero deberá analizar los datos necesarios del archivo xml utilizando ElementTree u otra biblioteca y luego cargarlo en el marco de datos.

Escenario No. 4

En la interfaz de usuario, se descarga un archivo xml con datos sobre objetos, que se genera sobre la marcha a partir de datos en la base de datos sujetos a ciertas condiciones (por ejemplo, estados, fechas, años u otros valores de parámetros para los objetos).

Tarea del probador: Compare la identificación de identificadores únicos de los objetos del archivo xml que se encuentran en el atributo de la etiqueta de la compañía con los identificadores de los objetos del resultado de la consulta SQL en la base de datos.

Redactamos un guión para el guión:

  • Guardamos los datos de la respuesta a la solicitud a la API en el archivo xml, obtenemos los datos necesarios de este archivo utilizando la biblioteca ElementTree, cargamos los datos en el primer marco de datos.
  • Ejecutamos la consulta SQL en la base de datos, exportamos los datos del resultado de la consulta al archivo csv, cargamos estos datos en el segundo marco de datos.
  • Combinamos los datos (fusión, por analogía con la unión externa en SQL) de dos marcos de datos recibidos en un nuevo marco de datos mediante un identificador único y descargamos los datos de este en un archivo de Excel.
  • A continuación, abra el archivo resultante y analice las líneas de datos.

Datos de ejemplo del archivo example4_csv.csv :



Datos de ejemplo del archivo example4_xml.xml : un



script de Python tiene este aspecto:

#   ElementTree
from xml.etree import ElementTree
#   pandas
import pandas as pd

#    xml-   
# (        )
tree = ElementTree.parse("example4_xml.xml")

#   
root = tree.getroot()

#  ,     
data_list = []
i = 1

#    -   id_type1  id_type2
for child in root.iter("companies"):
    for child_1 in child.iter("company"):
            data_list.append({"": i, "id": child_1.get("id_type1")
                                                or child_1.get("id_type2"), 
                              "  xml": ""})
            i += 1

#     data_list  -
df_from_xml = pd.DataFrame.from_dict(data_list, orient='columns')
print(df_from_xml)

#    csv-  -
df_from_csv = pd.read_csv('./example4_csv.csv', sep=';', encoding='utf-8')
print(df_from_csv)

#  -   -
# (   outer join  SQL)
df = df_from_csv.merge(df_from_xml, left_on='id', right_on="id", how='outer')
print(df)

#    Excel-
#          
# (      )
writer = pd.ExcelWriter('.xlsx')
df.to_excel(writer, '1')
writer.save()

Escenario 5

En la interfaz de usuario, la sección muestra datos sobre objetos en forma de tabla. Es posible cargar datos en un archivo de Excel.

La tarea del probador: comparar los datos de la tabla de particiones con los datos que se descargan en el archivo de Excel.

Redactamos un guión para el guión:

  • Solicitamos a los desarrolladores una consulta SQL en la base de datos del código que es responsable de enviar datos a la tabla de particiones en la interfaz de usuario.
  • Ejecutamos esta consulta SQL en la base de datos, cargamos los datos en un archivo csv y los cargamos en el primer marco de datos.
  • Cargamos los datos de la tabla de particiones al archivo de Excel en la interfaz de usuario y los cargamos en el segundo marco de datos.
  • (merge — outer join SQL) - - Excel-, Excel.
  • - pandas, / -/Excel- .

:

  • , Excel- UI, , , .

Además, se pueden usar scripts similares simplemente para transferir datos desde archivos json o archivos csv a archivos Excel. O bien, puede combinar datos de varios archivos de Excel en ciertas columnas y cargarlos en un nuevo archivo de Excel.

Conclusión


Estos son solo algunos ejemplos de cómo puede usar python + pandas para acelerar el proceso de prueba y encontrar errores. De hecho, los pandas tienen muchas más oportunidades para trabajar con datos, puede leer más sobre esto en la documentación de esta biblioteca.

Quizás su proyecto tenga otras opciones para usar dichos scripts y este artículo lo ayudará a comenzar a usarlos en el trabajo de los evaluadores.

Source: https://habr.com/ru/post/undefined/


All Articles