So bauen Sie einen einfachen Testdatenlader
Veröffentlicht: 2022-02-23Einleitung
SQL-Projekte sind in der Testing-Familie nicht sehr beliebt. Testingenieure bevorzugen normalerweise die Arbeit mit UI oder API. Aber es gibt viele Projekte, bei denen die Geschäftslogik in relationalen Datenbanken oder Data Warehouses liegt, und früher oder später müssen Sie DB/DW testen.
In diesen Projekten ist manuelles Testen, genauso wie in anderen, immer noch ein gültiger Ansatz und erfordert die Vorbereitung mehrerer Testdatenkonfigurationen. Dies kann schmerzhaft sein, wenn Sie mit mehreren SQL-Skripts für Testdaten, vielen DB-Objekten und DB-Schemata arbeiten. In diesem Artikel zeige ich Ihnen, wie Sie einen einfachen Testdatenlader erstellen.
Benutzeroberfläche
Wir werden Python und einen SQL-Server als Datenspeicher verwenden. Lassen Sie uns zunächst eine einfache Benutzeroberfläche für eine Desktop-App erstellen. Ich gehe davon aus, dass alle Bibliotheken bereits installiert sind, und wenn nicht, dann „pip install [package]“
Einstellungsfenster
System importieren willkürlich importieren aus PyQt4.QtCore importiere pyqtSlot,SIGNAL,SLOT aus PyQt4.QtGui importieren * aus PyQt4.QtCore importieren * datetime importieren app = QApplication(sys.argv) w = QWidget() w.setWindowTitle('Testdatengenerator') w.resize(180, 240) w.setFixedSize(800, 460) w.setStyleSheet("Hintergrundfarbe: weiß;")
Codeblock 1. Einstellungsfenster .
Beginnend mit einem leeren Fenster als Widget.
Fortschrittsanzeige
Lassen Sie uns nun einen Fortschrittsbalken zu unserem Testdatenladeprogramm hinzufügen. Es wird uns mitteilen, wenn das Laden oder Löschen von Daten beendet ist. Der Anfangswert ist offensichtlich auf 0 gesetzt.
Klasse QProgBar(QProgressBar): Wert = 0 @pyqtSlot() def Erhöhungswert (Fortschrittsbalken): progressBar.setValue(progressBar.value) progressBar.value = progressBar.value+1 bar = QProgBar(w) bar.resize(320,30) bar.setValue(0) bar.move(460.400)
Codeblock 2. Einstellen des Fortschrittsbalkens
Codeblock 2. enthält einige Dinge, die erklärt werden müssen:
- Wert steigern – eine Methode, die den Fortschrittsbalkenwert erhöht
- QProgBar(w) – Das QProgressBar-Widget stellt den Fortschrittsbalken bereit
Etiketten
Wir brauchen Beschriftungen für Buttons, Dropdowns, Eingabefelder etc.
lName = QLabel(w) {...} lName.setText("Name") lName.move(60,60) {...}
Code Block 3. Labels setzen
Und die Erklärung von Codeblock 3.
- {…} – Natürlich werde ich nicht den gesamten Code einfügen, also werde ich von nun an dieses {…} verwenden, um „Code-Fortsetzung hier“ zu informieren.
- QLabel(w) – Das QLabel-Widget stellt einen Text bereit
Buttons, Checkboxen und Eingabefelder
Lassen Sie uns einige weitere Elemente in unserer App durchgehen, beginnend mit Aktionsschaltflächen.
btnDelete = QPushButton('Testdaten löschen', w) btnLoad = QPushButton('Testdaten laden', w) {...} schema = QComboBox(w) schema.addItem("Testschema") schema.move(200,10) schema.resize(120,25) Datenbank = QLineEdit(w) database.move(30, 10) database.resize(120,25) database.setPlaceholderText("DB-Name") name1 = QCheckBox('Name 1', w) name1.move(30, 85) name1.setChecked(Wahr) {...}
Code Block 4. Labels setzen
Die in Codeblock 4 definierten App-Elemente sind:
- QPushButton('') – Das QPushButton-Widget stellt eine Schaltfläche bereit
- QComboBox(w) – Das QComboBox-Widget ist eine Dropdown-Liste
- QLineEdit(w) – Das QLineEdit-Widget ist eine einzeilige Texteingabe.
- QCheckBox – Das QCheckBox-Widget stellt ein Kontrollkästchen mit einer Textbeschriftung bereit
Aktionen
Jetzt kommt der lustige Teil. Wir werden die Aktionen erstellen und Signale mit Slots verbinden.
@pyqtSlot() def on_click_loadData(): bar.setValue(25) Namensliste = [] {...} db = str(datenbank.text()) {...} if(name1.isChecked()==True): nameList.append("Name 1") {...} if(len(nameList)>0): Name = str(nameList[randomValueGenerator(len(nameList))-1]) bar.setValue(50) if(str(schema.currentText())=='Testschema'): addTestData(db, 'Test', Name, {...}) {...} bar.setValue(75) bar.setValue(100) def on_click_deleteData(): bar.setValue(25) db = str(datenbank.text()) bar.setValue(50) if(str(schema.currentText())=='Testschema'): deleteTestData(db, 'Test') {...} bar.setValue(75) bar.setValue(100) {...} def ZufallswertGenerator(len): return random.randint(1,len) btnStructure.clicked.connect(on_click_createStructure) btnStructure.move(20, 400) btnStructure.resize(120,30) btnLoad.clicked.connect(on_click_loadData) btnLoad.move(160, 400) btnLoad.resize(120,30) btnDelete.clicked.connect(on_click_deleteData) btnDelete.move(300, 400) btnDelete.resize(120,30) w.show() app.exec_()
Code Block 5. Labels setzen

Es ist ein ziemlich langes Stück Code. Schauen wir uns genauer an, was wir gerade implementiert haben:
- on_click_loadData() – wir rufen die Funktion addTestData() auf und verwenden sie
btn.clicked.connect()- Funktion
- on_click_deleteData() – wir rufen die Funktion deleteTestData() auf und verwenden sie
btn.clicked.connect()- Funktion
- randomValueGenerator() – gibt einen zufälligen int-Wert aus dem definierten Bereich zurück
- btn.clicked.connect() – Wir verbinden das Signal mit dem Slot
- w.show() – Widget anzeigen
- app.exec_() - führt eine Anwendung aus
DB-Aktionen
Unsere App benötigt SQL-Aktionen, die mit Schaltflächenaktionen verbunden sind. Wir verwenden den pyodbc-Connector, um eine Verbindung zur SQL Server-Datenbank herzustellen. Ich gehe davon aus, dass das DB-Schema bereits vorhanden ist und wir keine DB-Objekte wie Tabellen usw. erstellen müssen.
Testdaten hinzufügen
Die Funktion addTestData übernimmt Werte von der Benutzeroberfläche und übergibt sie an die SQL-Abfrage. Aber gehen wir den gesamten Code durch:
- Öffnen der Verbindung zur SQL Server-Datenbank durch Definieren von dbAddress
- Festlegen des ID-Werts – Wenn die Tabellen-ID keine automatische Erhöhung ist, müssen wir den nächsten zu verwendenden Wert der ID kennen
- SQL-Abfragedefinition. Wir werden einige Werte von der Benutzeroberfläche übergeben.
pyodbc importieren ConfigParser importieren config = ConfigParser.RawConfigParser() config.read('../resources/env.properties') Liste = [] login = 'myFancyLogin' def addTestData(db, schema, Name {...}): Versuchen: dbAddress = "Driver={SQL Server};Server=localhost\SQLEXPRESS; Database="+db+";Trusted_Connection=yes; u;pwd=" cnx = pyodbc.connect (dbAdresse) cursor = cnx.cursor()+schema+"].[Kandidaten] ORDER BY ID DESC" id = returnValue(cnx, Cursor, id) ID = str(ID + 1) schema = str(schema) testQuery = 'SELECT DB_NAME() AS [Aktuelle Datenbank];' Kandidaten = "INSERT INTO ["+schema+"].[Kandidaten] VALUES("+Id+",'"+Name+"',{...}")" returnDBName(cnx, Cursor, Testabfrage) Liste = [Kandidaten] executeQuery(cnx, Cursor, Liste) außer pyodbc.Fehler als e: drucken print 'Fehler in der Funktion addTestData' anders: cnx.close()
Codeblock 6. Testdatenmethode hinzufügen
Testdaten löschen
Das Löschen von Testdaten wird von der Funktion deleteTestData(db,schema) behandelt. Es hat nur 2 Parameter (db,schema). Das bedeutet, dass wir den ganzen Tisch abräumen wollen, ohne den Inhalt zu tragen.
def deleteTestData(db, schema): Versuchen: dbAddress = "Driver={SQL Server};Server=localhost\SQLEXPRESS; Database="+db+";Trusted_Connection=yes; u;pwd=" cnx = pyodbc.connect (dbAdresse) Cursor = cnx.cursor() schema = str(schema) testQuery = 'SELECT DB_NAME() AS [Aktuelle Datenbank];' Kandidaten = "DELETE FROM ["+schema+"].[Kandidaten]" KandidatenVerarbeitet = "LÖSCHEN AUS ["+schema+"].[candidatesProcessed]" returnDBName(cnx, Cursor, Testabfrage) list = [Kandidaten, KandidatenBearbeitet] executeQuery(cnx, Cursor, Liste) außer: print 'Fehler in der Funktion deleteTestData' anders: cnx.close()
Codeblock 7. Testdatenmethode löschen
Dienstprogramme
Und einige utils-Funktionen, die von den Funktionen addTestData() und deleteTestData() verwendet werden:
def executeQuery(cnx, cursor, list): für i in der Liste: cursor.execute(i) cnx.commit() def returnDBName(cnx, cursor, dbQuery): cursor.execute (dbQuery) Wert = cursor.fetchone() Wert = Wert[0] Wert = str(Wert)
Codeblock 8. Util-Funktionen
Exe-Datei
Derzeit können wir unseren Code verwenden, wenn Python installiert ist, und wir können den Code kompilieren, aber was ist, wenn wir nur eine ausführbare Datei haben möchten? Die py2exe-Bibliothek ermöglicht das Erstellen einer ausführbaren Datei aus Python-Code (Code Block 9):
aus distutils.core import setup py2exe importieren setup(windows=[Name der Datei mit Widget], Datendateien = Datendateien, options={ 'py2exe': { "enthält":['sip'], "dll_excludes": ['MSVFW32.dll', 'AVIFIL32.dll', 'AVICAP32.dll', 'ADVAPI32.dll', 'CRYPT32.dll', 'WLDAP32.dll', 'MSVCP90.dll'] } })
Codeblock 9. Erstellen einer .exe-Datei
Das Ergebnis
Und hier ist das Ergebnis unserer Arbeit. Ich hoffe, Ihnen hat das Tutorial gefallen!
