So bauen Sie einen einfachen Testdatenlader

Veröffentlicht: 2022-02-23

Einleitung

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!