Python für den Tester: Wie kleine C-Pandas-Skripte helfen, große Datenmengen zu testen

Ich arbeite als Tester an einem Projekt, dessen Kern die Erfassung und Speicherung verschiedener Daten sowie die Erstellung verschiedener Berichte und das Hochladen von Dateien auf deren Grundlage ist. Bei der Erstellung solcher Berichte wird eine Vielzahl von Bedingungen für die Datenauswahl berücksichtigt. Daher müssen Sie beim Testen viel mit SQL-Abfragen in der Datenbank arbeiten. Um jedoch die korrekte Auswahl der Daten zu überprüfen und nach überschüssigen / fehlenden Daten zu suchen, reicht dies oft nicht aus. Daher musste ich nach zusätzlichen Tools suchen.

Da ich bereits einige grundlegende Python-Kenntnisse hatte, beschloss ich, kleine Skripte zu schreiben, die es mir ermöglichen, etwas mit den vorhandenen Daten zu tun und dadurch den Testprozess zu vereinfachen und zu beschleunigen. In diesem Artikel werde ich Ihnen erzählen, was daraus geworden ist.

Entwerfen eines Skriptskripts


Um ein Skript zu schreiben, müssen Sie herausfinden, was genau das Skript tun soll, welche Daten eingegeben werden müssen und welche Daten voraussichtlich ausgegeben werden.

Beispielschritte für das Szenario:

  1. Wir erhalten eine Datei mit Daten in einem bestimmten Format (oder mehreren Dateien)
  2. Daten aus Datei / Dateien abrufen
  3. Wir wählen die notwendigen Daten aus
  4. Wir führen einige Operationen an Daten durch
  5. Bei Bedarf laden wir Daten in eine Excel-Datei hoch (normalerweise ist dieses Format für die weitere Analyse und Speicherung am bequemsten).

Dann müssen Sie darüber nachdenken, wie und wo Sie Eingaben erhalten können. Dies kann eine manuell erstellte Datei mit Daten sein, die Daten unter Berücksichtigung von Filtern in eine Benutzeroberfläche in eine Datei hochlädt, eine Datei mit Datenanalyse mithilfe eines anderen Skripts, eine Datei zum Hochladen der Ergebnisse einer SQL-Abfrage in die Datenbank (Sie können Daten schnell aus der Datenbank in eine CSV-Datei hochladen), json -Datei oder XML-Datei mit Daten aus der Antwort auf eine Anfrage an die API usw.

Wir schreiben Skripte in Python mit Pandas und anderen Bibliotheken


Um Skripte in Python zu schreiben , müssen Sie einen Interpreter und eine geeignete IDE installieren. Es ist auch am besten, eine separate virtuelle Umgebung für dieses Projekt zu erstellen .

Ich verwende verschiedene Bibliotheken für Skripte, einige davon sind integrierte Python-Bibliotheken , andere müssen zusätzlich installiert werden:

  • pandas ist eine Bibliothek zur Datenanalyse. Sie können mit Daten aus Dateien verschiedener Formate arbeiten und mithilfe einer SQL-Abfrage Daten direkt aus der Datenbank empfangen. Daten aus Dateien werden in Datenrahmen geladen (visuell dieselben Tabellen wie in Excel), mit Daten, in denen Sie bereits verschiedene Vorgänge ausführen können: Kombinieren Sie Daten aus verschiedenen Datenrahmen analog zu join / union in SQL und wählen Sie die gewünschten Daten aus Vergleichen Sie unter bestimmten Bedingungen Daten in verschiedenen Spalten des Datenrahmens usw.
  • openpyxl, xlrd - Bibliotheken für die Arbeit mit Excel.

Das einfachste Skript-Framework für die Arbeit mit Daten aus CSV-, JSON- und Excel-Dateien lautet wie folgt:

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

In diesem Skript werden Daten aus einer Datei des erforderlichen Formats in einen Datenrahmen geladen, die erforderlichen Daten ausgewählt und einige Operationen an ihnen ausgeführt. Anschließend werden die Daten in eine neue Excel-Datei geschrieben.

Wenn Sie mit Daten arbeiten müssen, die als Ergebnis einer SQL-Abfrage in die Datenbank erhalten wurden, können Sie diese nicht in eine CSV-Datei exportieren, sondern sie sofort in einen Datenrahmen übertragen, indem Sie eine SQL-Abfrage in der Datenbank im Skript selbst ausführen:

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

Wenn Sie Daten aus einer XML-Datei abrufen müssen, können Sie die dafür vorgesehenen Bibliotheken verwenden. Ich benutze die eingebaute Bibliothek ElementTree .

Wenn die Daten in einem Datenrahmen empfangen werden, können Sie sie sofort mit Daten aus einem anderen Datenrahmen (Analoga von Join oder Union in SQL) kombinieren oder einige Operationen an ihnen ausführen, z. B. Duplikate entfernen, Zeilen mit leeren Werten in bestimmten Zellen entfernen , Daten in mehreren Spalten vergleichen, die gewünschten Zeilen / Spalten auswählen usw. Lesen Sie mehr in der Dokumentation für Pandas.

Optionen für die Skriptverwendung


Und jetzt schalten wir das Hauptwerkzeug des Testers ein und wählen die Daten / Funktionen in unserem Projekt aus, um zu überprüfen, welche solchen Skripte nützlich wären.

Für die Skripte wurden Dateien mit einer kleinen Menge von Testdaten erstellt, die mit generierten Daten generiert wurden . In Wirklichkeit enthalten Datendateien Zehntausende von Zeilen und eine große Anzahl von Spalten.

Szenario 1

Es gibt drei Dateien im CSV-Format mit Daten. Für jede Datenzeile gibt es ein Feld mit einer eindeutigen ID. Daten aus diesen Dateien werden unter Berücksichtigung bestimmter Bedingungen ausgewählt und in eine Tabelle in der Datenbank eingegeben. Diese Daten werden dann in einem Bericht in Form einer Tabelle auf der Benutzeroberfläche angezeigt. Es ist möglich, Daten auf einer Benutzeroberfläche in eine Excel-Datei hochzuladen.

Angenommen, die Bedingungen für die Auswahl von Daten für einen Bericht aus Quelldateien lauten wie folgt:

  • Dateien können Duplikate nach ID haben. In einem Bericht sollte ein Datensatz mit derselben Kennung nur einmal berücksichtigt werden (in diesem Fall wählen wir einfach eine der Zeilen mit dieser Kennung aus den Daten aus).
  • Zeilen mit fehlenden Daten in der Spaltenzelle reg_date sollten nicht gezählt werden.
  • Tatsächlich kann es mehr Auswahlbedingungen geben, die Daten können auch mit den bereits im System vorhandenen Daten verglichen werden, und im Bericht werden nur sich überschneidende Daten nach ID angezeigt. Beispielsweise werden jedoch nur die beiden oben angegebenen Bedingungen berücksichtigt.

Die Aufgabe des Testers: Überprüfen Sie, ob die Zeilen mit den erforderlichen Objekten korrekt aus den Quelldateien ausgewählt wurden und ob alle diese Objekte im Bericht auf der Benutzeroberfläche angezeigt werden.

Wir verfassen ein Skript für das Skript:

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

In der endgültigen Datei enthalten die Daten nur eine Spalte mit der ID, wenn die Namen der Spalten in verschiedenen Datenrahmen übereinstimmen und möglicherweise nicht klar ist, welche Spalten / Zeilen aus welcher Datei stammen. Daher benenne ich die Spalten mit einer eindeutigen Kennung entweder nach unterschiedlichen Namen in den Dateien oder füge jeder Datei eine separate Spalte "Zeilen aus einer solchen und solchen Datei" hinzu und füge "Ja" ein. Wenn Sie dann die resultierende Excel-Datei analysieren, ist es praktisch, nach dieser Spalte zu filtern da Sie enthalten immer einen Wert, und wenn Sie nach ihnen filtern, können Sie bereits verstehen, welche Daten in den entsprechenden Spalten voneinander abweichen.

Beispieldaten aus der Datei example1_csv_1.csv :



Beispieldaten aus der Datei report_UI.xlsx : Ein



Python-Skript sieht folgendermaßen aus:

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

Einschränkungen:

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

Szenario Nr. 2
Der Abschnitt enthält Daten in Form einer Tabelle für bestimmte Objekte aus einer Hand. Das System empfängt Daten von einer zweiten Quelle (Integration) und aktualisiert die vorhandenen Tabellendaten mit diesen Daten. Jeder Datensatz in der Tabelle enthält Daten für ein Objekt mit einer eindeutigen Kennung. Wenn aus einer neuen Quelle die Daten eines Objekts nach Kennung mit den Daten eines vorhandenen Objekts übereinstimmen, werden alle Felder eines vorhandenen Datensatzes mit Daten aus einer neuen Quelle aktualisiert (bestätigt). Wenn die Tabelle noch kein Objekt mit einem Bezeichner aus der zweiten Quelle enthält, wird in der Tabelle ein neuer Datensatz mit Daten aus der neuen Quelle erstellt. Daten aus dem zweiten System können vorab in eine JSON-Datei hochgeladen werden.

Die Aufgabe des Testers:Bereiten Sie im Voraus eine Datei mit Daten für den Test vor, um zu überprüfen, ob die vorhandenen Datensätze korrekt aktualisiert und mit einem Bestätigungszeichen in der Datenbank versehen wurden, wenn eine Übereinstimmung mit der Kennung vorliegt. Neue Datensätze werden korrekt erstellt und mit dem Zeichen des Hinzufügens zur Datenbank gekennzeichnet, wenn Datensätze mit solchen vorhanden sind Die Kennung war noch nicht.

Wir verfassen ein Skript für das Skript:

  • Wir laden die Daten aus der Partitionstabelle in die Excel-Datei auf der Benutzeroberfläche hoch (wenn dies nicht möglich ist, können Sie die Daten aus dem Ergebnis der SQL-Abfrage, die im Code zur Ausgabe von Daten in diese Tabelle auf der Benutzeroberfläche verwendet wird, jederzeit exportieren) und füllen die Daten daraus in den ersten Datenrahmen .
  • Wir erhalten die JSON-Datei mit Daten aus der zweiten Quelle und laden sie in den zweiten Datenrahmen.
  • (merge — outer join SQL) - - Excel-, . , , .

:

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

Szenario 3

Es wird eine Anforderung an die System-API gestellt, auf die Daten zu Objekten im JSON-Format empfangen werden.

Aufgabe des Testers: Vergleichen Sie die Daten aus der Antwort auf die Anforderung an die API mit den Daten aus dem Ergebnis der SQL-Abfrage in der Datenbank.

Wir verfassen ein Skript für das Skript:

  • Wir führen die SQL-Abfrage in der Datenbank aus, exportieren die Daten aus dem Abfrageergebnis in eine CSV-Datei und laden diese Daten in den ersten Datenrahmen.
  • Wir speichern die Daten aus der Antwort auf die Anfrage an die API in der JSON-Datei und laden die Daten aus der Datei in den zweiten Datenrahmen.
  • Wir kombinieren die Daten (Merge - analog zu Outer Join in SQL) aus zwei empfangenen Datenrahmen durch eine eindeutige Kennung zu einem neuen Datenrahmen und entladen die Daten daraus in eine Excel-Datei, in der wir bereits Daten mit den Funktionen von nach Spalten vergleichen Excel
  • Oder die Daten zu den Spalten im allgemeinen Datenrahmen können mit Pandas verglichen werden, während Zeilen mit denselben / unterschiedlichen Daten in den Spalten zur Analyse in einen neuen Datenrahmen / eine neue Excel-Datei entladen werden.

Beispieldaten aus der Datei example3_csv.csv :



Beispieldaten aus der Datei 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"
    },
...
]

Das Python-Skript sieht folgendermaßen aus:

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


Einschränkungen:

  • Wenn Sie mit Dateien mit einer sehr großen Anzahl von Zeilen arbeiten, müssen Sie diese in separate Dateien aufteilen (hier müssen Sie versuchen, ich habe selten Dateien mit mehr als 30.000 Zeilen).
  • Wenn die json-Datei mehrere Verschachtelungsebenen von Objekten / Datenarrays enthält, werden sie von den internen Ebenen als Objekt / Array in die Zelle geladen. Daher ist die Arbeit mit json-Dateien mit Pandas nur für Daten ohne übermäßige Verschachtelung von Objekten geeignet / Arrays.
  • API SQL- , SQL- .

Wenn die Antwort auf die Anforderung an die API im XML-Format vorliegt, müssen Sie zuerst die erforderlichen Daten aus der XML-Datei mit ElementTree oder einer anderen Bibliothek analysieren und dann in den Datenrahmen laden.

Szenario Nr. 4

Auf der Benutzeroberfläche wird eine XML-Datei mit Daten zu Objekten heruntergeladen, die unter bestimmten Bedingungen (z. B. Status, Datum, Jahr oder andere Parameterwerte für Objekte) aus Daten in der Datenbank generiert werden.

Aufgabe des Testers: Vergleichen Sie die ID der eindeutigen Kennungen der Objekte aus der XML-Datei, die sich im Attribut des Firmen-Tags befinden, mit den Kennungen der Objekte aus dem Ergebnis der SQL-Abfrage in der Datenbank.

Wir verfassen ein Skript für das Skript:

  • Wir speichern die Daten aus der Antwort auf die Anfrage an die API in der XML-Datei, holen die erforderlichen Daten aus dieser Datei mithilfe der ElementTree-Bibliothek ab und laden die Daten in den ersten Datenrahmen.
  • Wir führen die SQL-Abfrage in der Datenbank aus, exportieren die Daten aus dem Abfrageergebnis in die CSV-Datei und laden diese Daten in den zweiten Datenrahmen.
  • Wir kombinieren die Daten (Merge - analog zu Outer Join in SQL) aus zwei empfangenen Datenrahmen durch eine eindeutige Kennung zu einem neuen Datenrahmen und entladen die Daten daraus in eine Excel-Datei.
  • Öffnen Sie als Nächstes die resultierende Datei und analysieren Sie die Datenzeilen.

Beispieldaten aus der Datei example4_csv.csv :



Beispieldaten aus der Datei example4_xml.xml : Ein



Python-Skript sieht folgendermaßen aus:

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

Szenario 5

Auf der Benutzeroberfläche werden im Abschnitt Daten zu Objekten in Form einer Tabelle angezeigt. Es ist möglich, Daten in eine Excel-Datei hochzuladen.

Die Aufgabe des Testers: Vergleichen Sie die Daten aus der Partitionstabelle mit den Daten, die in die Excel-Datei heruntergeladen werden.

Wir verfassen ein Skript für das Skript:

  • Wir bitten Entwickler um eine SQL-Abfrage in der Datenbank anhand des Codes, der für die Ausgabe von Daten in die Partitionstabelle auf der Benutzeroberfläche verantwortlich ist.
  • Wir führen diese SQL-Abfrage in der Datenbank aus, laden die Daten in eine CSV-Datei hoch und laden die Daten daraus in den ersten Datenrahmen.
  • Wir laden die Daten aus der Partitionstabelle in die Excel-Datei auf der Benutzeroberfläche hoch und laden die Daten daraus in den zweiten Datenrahmen.
  • (merge — outer join SQL) - - Excel-, Excel.
  • - pandas, / -/Excel- .

:

  • , Excel- UI, , , .

Ähnliche Skripte können auch einfach verwendet werden, um Daten von JSON-Dateien oder CSV-Dateien in Excel-Dateien zu übertragen. Sie können auch Daten aus mehreren Excel-Dateien in bestimmten Spalten kombinieren und in eine neue Excel-Datei hochladen.

Fazit


Dies sind nur einige Beispiele dafür, wie Sie mit Python + Pandas den Testprozess beschleunigen und Fehler finden können. In der Tat hat Pandas viel mehr Möglichkeiten, mit Daten zu arbeiten. Weitere Informationen hierzu finden Sie in der Dokumentation zu dieser Bibliothek.

Vielleicht hat Ihr Projekt andere Optionen für die Verwendung solcher Skripte, und dieser Artikel hilft Ihnen dabei, sie in der Arbeit von Testern zu verwenden.

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


All Articles