Python pour le testeur: comment les petits scripts pandas c aident à tester de grands ensembles de données

Je travaille en tant que testeur sur un projet dont l'essentiel est la collecte et le stockage de diverses donnĂ©es et la formation de divers rapports et tĂ©lĂ©chargements de fichiers sur leur base. Lors de la gĂ©nĂ©ration de tels rapports, un grand nombre de conditions de sĂ©lection des donnĂ©es sont prises en compte et, par consĂ©quent, lors des tests, vous devez beaucoup travailler avec les requĂȘtes SQL dans la base de donnĂ©es. Mais pour vĂ©rifier la sĂ©lection correcte des donnĂ©es et rechercher les donnĂ©es excĂ©dentaires / manquantes, cela ne suffit souvent pas, j'ai donc dĂ» chercher des outils supplĂ©mentaires pour cela.

Comme j'avais déjà quelques connaissances de base en python, j'ai décidé d'essayer d'écrire de petits scripts qui nous permettraient de faire quelque chose avec les données existantes et ainsi de faciliter et d'accélérer le processus de test. Dans cet article, je vais vous dire ce qui en est sorti.

Conception d'un script de script


Pour Ă©crire un script, vous devez comprendre exactement ce que le script doit faire, quelles donnĂ©es doivent ĂȘtre entrĂ©es et quelles donnĂ©es devraient ĂȘtre sorties.

Exemples d'étapes pour le scénario:

  1. Nous obtenons un fichier avec des données dans un certain format (ou plusieurs fichiers)
  2. Obtenir des données à partir d'un fichier / fichiers
  3. Nous sélectionnons les données nécessaires
  4. Nous effectuons certaines opérations sur les données
  5. Nous téléchargeons les données dans un fichier Excel, si nécessaire (généralement ce format est le plus pratique pour une analyse et un stockage approfondis)

Ensuite, vous devez rĂ©flĂ©chir Ă  comment et oĂč vous pouvez obtenir des informations. Cela peut ĂȘtre un fichier crĂ©Ă© manuellement avec des donnĂ©es, le tĂ©lĂ©chargement de donnĂ©es vers une interface utilisateur dans un fichier en tenant compte des filtres, un fichier avec des donnĂ©es d'analyse Ă  l'aide d'un autre script, un fichier pour tĂ©lĂ©charger les rĂ©sultats d'une requĂȘte SQL dans la base de donnĂ©es (vous pouvez rapidement tĂ©lĂ©charger des donnĂ©es vers un fichier csv Ă  partir de la base de donnĂ©es), json -fichier ou fichier xml avec les donnĂ©es de la rĂ©ponse Ă  une demande Ă  l'API, etc.

Nous Ă©crivons des scripts en python en utilisant des pandas et d'autres bibliothĂšques


Pour écrire des scripts en python, vous devez installer un interpréteur et un IDE approprié. Il est également préférable de créer un environnement virtuel distinct pour ce projet.

J'utilise diffĂ©rentes bibliothĂšques pour les scripts, certaines d'entre elles sont des bibliothĂšques python intĂ©grĂ©es , certaines doivent ĂȘtre installĂ©es en plus:

  • pandas est une bibliothĂšque d'analyse de donnĂ©es. Il vous permet de travailler avec des donnĂ©es de fichiers de diffĂ©rents formats, ainsi que de recevoir des donnĂ©es directement de la base de donnĂ©es Ă  l'aide d'une requĂȘte SQL. Les donnĂ©es des fichiers sont chargĂ©es dans des blocs de donnĂ©es (visuellement les mĂȘmes tableaux que dans Excel), avec des donnĂ©es dans lesquelles vous pouvez dĂ©jĂ  effectuer diffĂ©rentes opĂ©rations: combiner des donnĂ©es de diffĂ©rents blocs de donnĂ©es par analogie avec jointure / union en SQL, sĂ©lectionnez les donnĂ©es dont vous avez besoin sous certaines conditions, comparer les donnĂ©es dans diffĂ©rentes colonnes de la trame de donnĂ©es, etc.
  • openpyxl, xlrd - bibliothĂšques pour travailler avec Excel.

Le cadre de script le plus simple pour travailler avec des données à partir de fichiers csv, json, Excel est le suivant:

#   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()

Dans ce script, les données d'un fichier du format souhaité sont chargées dans une trame de données, les données nécessaires sont sélectionnées et certaines opérations sont effectuées sur elles, puis les données sont écrites dans un nouveau fichier Excel.

Si vous devez travailler avec des donnĂ©es obtenues Ă  la suite d'une requĂȘte SQL dans la base de donnĂ©es, vous ne pouvez pas les exporter vers un fichier csv, mais les placer immĂ©diatement dans un bloc de donnĂ©es en exĂ©cutant une requĂȘte SQL dans la base de donnĂ©es dans le script lui-mĂȘme:

#   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 vous devez obtenir des données à partir d'un fichier xml, vous pouvez utiliser les bibliothÚques conçues à cet effet. J'utilise la bibliothÚque intégrée ElementTree .

Lorsque les données sont reçues dans une trame de données, vous pouvez immédiatement les combiner avec des données d'une autre trame de données (analogues de jointure ou d'union dans SQL) ou effectuer certaines opérations sur celles-ci, par exemple, supprimer les doublons, supprimer les lignes avec des valeurs vides dans certaines cellules , comparez les données dans plusieurs colonnes, sélectionnez les lignes / colonnes souhaitées, etc. En savoir plus dans la documentation pour les pandas.

Options d'utilisation des scripts


Et maintenant, nous activons l'outil principal du testeur et sélectionnons les données / fonctionnalités de notre projet, pour vérifier quels scripts seraient utiles.

Des fichiers contenant une petite quantité de données de test générées à l'aide des données générées ont été créés pour les scripts . En réalité, les fichiers de données contiennent des dizaines de milliers de lignes et un grand nombre de colonnes.

Scénario # 1

Il y a trois fichiers au format csv avec des données. Pour chaque ligne de données, il existe un champ avec un identifiant unique. Les données de ces fichiers sont sélectionnées en tenant compte de certaines conditions et saisies dans un tableau de la base de données, puis ces données sont affichées dans un rapport sous la forme d'un tableau sur l'interface utilisateur. Il est possible de télécharger des données sur une interface utilisateur vers un fichier Excel.

Supposons que les conditions de sélection des données pour un rapport à partir de fichiers source soient les suivantes:

  • Les fichiers peuvent avoir des doublons par identifiant, dans un rapport, un enregistrement avec le mĂȘme identifiant ne doit ĂȘtre pris en compte qu'une seule fois (dans ce cas, nous sĂ©lectionnons simplement l'une des lignes avec cet identifiant dans les donnĂ©es).
  • Les lignes avec des donnĂ©es manquantes dans la cellule de la colonne reg_date ne doivent pas ĂȘtre comptĂ©es.
  • En fait, il peut y avoir plus de conditions de sĂ©lection, les donnĂ©es peuvent Ă©galement ĂȘtre comparĂ©es aux donnĂ©es dĂ©jĂ  prĂ©sentes dans le systĂšme et seules les donnĂ©es entrecroisĂ©es par id seront affichĂ©es dans le rapport, mais par exemple nous ne prendrons en compte que les deux conditions indiquĂ©es ci-dessus.

La tùche du testeur: Vérifier que les lignes avec les objets nécessaires sont correctement sélectionnées dans les fichiers source et que tous ces objets sont affichés dans le rapport sur l'interface utilisateur.

Nous composons un script pour le script:

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

Dans le fichier final, les donnĂ©es ne contiendront qu'une seule colonne avec id, si les noms des colonnes dans des trames de donnĂ©es diffĂ©rentes coĂŻncident, et il peut ne pas ĂȘtre clair quelles colonnes / lignes de quel fichier provenaient. Par consĂ©quent, soit je nomme les colonnes avec un identifiant unique par des noms diffĂ©rents dans les fichiers, soit j'ajoute une colonne distincte «Lignes d'un fichier de tel ou tel» Ă  chaque fichier et y ajoute «Oui» - puis, lors de l'analyse du fichier Excel rĂ©sultant, il est pratique de filtrer par cette colonne parce que ils contiennent toujours une valeur et, en les filtrant, vous pouvez dĂ©jĂ  comprendre quelles donnĂ©es divergent dans les colonnes correspondantes.

Exemple de données de example1_csv_1.csv fichier :



Exemple de données de report_UI.xlsx fichier : A



ressemble ce script python:

#   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()

Limites:

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

Scénario n ° 2
La section contient des donnĂ©es sous forme de tableau pour certains objets Ă  partir d'une seule source. Le systĂšme recevra les donnĂ©es d'une deuxiĂšme source (intĂ©gration) et mettra Ă  jour les donnĂ©es de table existantes avec ces donnĂ©es. Chaque enregistrement de la table correspond aux donnĂ©es d'un objet dotĂ© d'un identifiant unique. Si Ă  partir d'une nouvelle source les donnĂ©es d'objet par identifiant coĂŻncident avec les donnĂ©es d'un objet existant, alors tous les champs de l'enregistrement existant sont mis Ă  jour avec les donnĂ©es de la nouvelle source (confirmĂ©es). Si la table n'a pas encore d'objet avec un identifiant de la deuxiĂšme source, un nouvel enregistrement est crĂ©Ă© dans la table avec les donnĂ©es de la nouvelle source. Les donnĂ©es du deuxiĂšme systĂšme peuvent ĂȘtre tĂ©lĂ©chargĂ©es Ă  l'avance dans un fichier json.

La tùche du testeur:Préparez à l'avance un fichier contenant des données pour le test, afin qu'aprÚs la fin de l'implémentation, vérifiez que les enregistrements existants sont correctement mis à jour et qu'ils soient apposés avec un signe de confirmation dans la base de données, s'il y a correspondance par identifiant, et que de nouveaux enregistrements sont correctement créés et qu'ils sont marqués avec le signe de l'ajout à la base de données, si les enregistrements avec tels l'identifiant n'était pas encore.

Nous composons un script pour le script:

  • Nous tĂ©lĂ©chargeons les donnĂ©es de la table de partition dans le fichier Excel sur l'interface utilisateur (si cela n'est pas possible, vous pouvez toujours exporter les donnĂ©es du rĂ©sultat de la requĂȘte SQL utilisĂ©e dans le code pour sortir les donnĂ©es vers cette table sur l'interface utilisateur) et remplir les donnĂ©es de celui-ci dans le premier bloc de donnĂ©es .
  • Nous obtenons le fichier json avec des donnĂ©es de la deuxiĂšme source et le chargeons dans la deuxiĂšme trame de donnĂ©es.
  • (merge — outer join SQL) - - Excel-, . , , .

:

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

Scénario 3

Une demande est adressée à l'API systÚme, en réponse à laquelle les données sur les objets au format json sont reçues.

TĂąche du testeur: comparer les donnĂ©es de la rĂ©ponse Ă  la demande Ă  l'API avec les donnĂ©es du rĂ©sultat de la requĂȘte SQL dans la base de donnĂ©es.

Nous composons un script pour le script:

  • Nous exĂ©cutons la requĂȘte SQL dans la base de donnĂ©es, exportons les donnĂ©es du rĂ©sultat de la requĂȘte vers un fichier csv, chargeons ces donnĂ©es dans le premier bloc de donnĂ©es.
  • Nous sauvegardons les donnĂ©es de la rĂ©ponse Ă  la demande Ă  l'API dans le fichier json, chargeons les donnĂ©es du fichier dans la deuxiĂšme trame de donnĂ©es.
  • Nous combinons les donnĂ©es (fusion - par analogie avec la jointure externe en SQL) de deux trames de donnĂ©es reçues dans une nouvelle trame de donnĂ©es par un identifiant unique et en dĂ©chargeons les donnĂ©es dans un fichier Excel, dans lequel nous comparerons dĂ©jĂ  les donnĂ©es par colonnes en utilisant les fonctions de Exceller
  • Ou les donnĂ©es sur les colonnes dans le bloc de donnĂ©es gĂ©nĂ©rales peuvent ĂȘtre comparĂ©es Ă  l'aide de pandas, tout en dĂ©chargeant les lignes avec les mĂȘmes donnĂ©es / des donnĂ©es diffĂ©rentes dans les colonnes dans un nouveau bloc de donnĂ©es / fichier Excel pour analyse.

Exemples de données du fichier example3_csv.csv :



Exemples de données du fichier 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"
    },
...
]

Le script python ressemble Ă  ceci:

#   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()


Limites:

  • Lorsque vous travaillez avec des fichiers avec un trĂšs grand nombre de lignes, vous devrez les diviser en fichiers sĂ©parĂ©s (ici, vous devez essayer, j'ai rarement des fichiers de plus de 30 000 lignes).
  • Si le fichier json a plusieurs niveaux d'imbrication d'objets / tableaux de donnĂ©es, alors Ă  partir des niveaux internes, ils seront chargĂ©s dans la cellule en tant qu'objet / tableau, donc travailler avec des fichiers json avec pandas n'est pratique que pour les donnĂ©es sans imbrication excessive d'objets / tableaux.
  • API SQL- , SQL- .

Si la réponse à la demande adressée à l'API est au format xml, vous devrez d'abord analyser les données nécessaires à partir du fichier xml à l'aide d'ElementTree ou d'une autre bibliothÚque, puis les charger dans le bloc de données.

Scénario n ° 4

Sur l'interface utilisateur, un fichier xml contenant des données sur les objets est téléchargé, qui est généré à la volée à partir des données de la base de données sous certaines conditions (par exemple, les statuts, les dates, les années ou d'autres valeurs de paramÚtres pour les objets sont pris en compte).

TĂąche du testeur: comparer l'ID unique des identifiants des objets du fichier xml qui se trouvent dans l'attribut de la balise de sociĂ©tĂ© avec les identifiants des objets du rĂ©sultat de la requĂȘte SQL dans la base de donnĂ©es.

Nous composons un script pour le script:

  • Nous sauvegardons les donnĂ©es de la rĂ©ponse Ă  la demande Ă  l'API dans le fichier xml, obtenons les donnĂ©es nĂ©cessaires Ă  partir de ce fichier en utilisant la bibliothĂšque ElementTree, chargeons les donnĂ©es dans le premier bloc de donnĂ©es.
  • Nous exĂ©cutons la requĂȘte SQL dans la base de donnĂ©es, exportons les donnĂ©es du rĂ©sultat de la requĂȘte vers le fichier csv, chargeons ces donnĂ©es dans le deuxiĂšme bloc de donnĂ©es.
  • Nous combinons les donnĂ©es (fusion - par analogie avec la jointure externe en SQL) de deux trames de donnĂ©es reçues dans une nouvelle trame de donnĂ©es par un identifiant unique et dĂ©chargeons les donnĂ©es de celui-ci dans un fichier Excel.
  • Ensuite, ouvrez le fichier rĂ©sultant et analysez les lignes de donnĂ©es.

Exemples de données du fichier example4_csv.csv :



Exemples de données du fichier example4_xml.xml : Un



script python ressemble Ă  ceci:

#   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()

Scénario 5

Dans l'interface utilisateur, la section affiche des données sur les objets sous la forme d'un tableau. Il est possible de télécharger des données dans un fichier Excel.

La tùche du testeur: comparer les données de la table de partition avec les données téléchargées dans le fichier Excel.

Nous composons un script pour le script:

  • Nous demandons aux dĂ©veloppeurs une requĂȘte SQL dans la base de donnĂ©es Ă  partir du code qui est responsable de la sortie des donnĂ©es vers la table de partition sur l'interface utilisateur.
  • Nous exĂ©cutons cette requĂȘte SQL dans la base de donnĂ©es, tĂ©lĂ©chargeons les donnĂ©es dans un fichier csv, chargeons les donnĂ©es de celui-ci dans la premiĂšre trame de donnĂ©es.
  • Nous tĂ©lĂ©chargeons les donnĂ©es de la table de partition vers le fichier Excel sur l'interface utilisateur et chargeons les donnĂ©es de celle-ci dans le deuxiĂšme bloc de donnĂ©es.
  • (merge — outer join SQL) - - Excel-, Excel.
  • - pandas, / -/Excel- .

:

  • , Excel- UI, , , .

Des scripts similaires peuvent Ă©galement ĂȘtre utilisĂ©s simplement pour transfĂ©rer des donnĂ©es de fichiers json ou de fichiers csv vers des fichiers Excel. Ou, vous pouvez combiner les donnĂ©es de plusieurs fichiers Excel dans certaines colonnes et les tĂ©lĂ©charger dans un nouveau fichier Excel.

Conclusion


Ce ne sont que quelques exemples de la façon dont vous pouvez utiliser python + pandas pour accélérer le processus de test et trouver des bogues. En fait, les pandas ont beaucoup plus de possibilités de travailler avec des données, vous pouvez en savoir plus à ce sujet dans la documentation de cette bibliothÚque.

Peut-ĂȘtre que votre projet a d'autres options pour utiliser de tels scripts et cet article vous aidera Ă  commencer Ă  les utiliser dans le travail des testeurs.

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


All Articles