Come costruire un semplice caricatore di dati di prova

Pubblicato: 2022-02-23

Introduzione

I progetti SQL non sono molto popolari nella famiglia di test. Gli ingegneri di test di solito preferiscono lavorare con l'interfaccia utente o l'API. Ma ci sono molti progetti in cui la logica di business risiede nei database relazionali o nei data warehouse e prima o poi dovrai fare dei test su DB/DW.

In questi progetti, come in altri, il test manuale è ancora un approccio valido e richiede la preparazione di più configurazioni di dati di test. Questo può essere doloroso quando si lavora con più script sql di dati di test, molti oggetti DB e schemi DB. In questo articolo, ti mostrerò come creare un semplice caricatore di dati di test.

Interfaccia utente

Utilizzeremo Python e SQL Server come archivio dati. Innanzitutto creiamo una semplice interfaccia utente per un'app desktop. Presumo che tutte le librerie siano già installate e, in caso contrario, "pip install [pacchetto]"

Finestra di impostazione

 importazione sist
importa a caso
da PyQt4.QtCore importa pyqtSlot,SIGNAL,SLOT
da importazione PyQt4.QtGui *
da importazione PyQt4.QtCore *
importa data e ora

       app = QApplication(sys.argv)
       w = QWidget()
       w.setWindowTitle('Test Data Generator')
       w.resize(180, 240)
       w.setFixedSize(800, 460)

       w.setStyleSheet("colore di sfondo: bianco;")

Blocco codice 1. Finestra di impostazione .

A partire da una finestra vuota come widget.

Barra di avanzamento

Ora aggiungiamo una barra di avanzamento al nostro caricatore di dati di test. Ci dirà quando il caricamento o l'eliminazione dei dati è terminato. Il valore iniziale è ovviamente impostato a 0.

 classe QProgBar(QProgressBar):

       valore = 0

   @pyqtSlot()
   def aumentoValore(progressBar):
           progressBar.setValue(progressBar.value)
           progressBar.value = progressBar.value+1

barra = QProgBar(w)
bar.resize(320,30)
bar.setValue(0)
barra.sposta(460.400)

Blocco codice 2. Impostazione della barra di avanzamento

Code Block 2. contiene alcune cose da spiegare:

  • aumento valore un metodo che aumenterà il valore della barra di avanzamento
  • QProgBar(w) Il widget QProgressBar fornisce la barra di avanzamento

Etichette

Abbiamo bisogno di etichette per pulsanti, menu a discesa, campi di input ecc.

 lNome = QEtichetta(w)
{...}

lName.setText("Nome")
lNome.mossa(60,60)
{...}

Blocco codice 3. Impostazione etichette

E la spiegazione del Code Block 3.

  • {…} Ovviamente, non inserirò tutto il codice, quindi d'ora in poi userò questo {…} per informare la "continuazione del codice qui".
  • QLabel(w) -Il widget QLabel fornisce un testo

Pulsanti, caselle di controllo e campi di input

Esaminiamo altri elementi della nostra app, a partire dai pulsanti di azione.

 btnDelete = QPushButton('Elimina dati di prova', w)
btnLoad = QPushButton('Carica dati test', w)
{...}

schema = QComboBox(w)
schema.addItem("Schema di prova")
schema.move(200,10)
schema.resize(120,25)

database = QLineEdit(w)
database.move(30, 10)
database.resize(120,25)
database.setPlaceholderText("Nome DB")

nome1 = QCheckBox('Nome 1', w)
nome1.mossa(30, 85)
name1.setChecked(True)
{...}

Blocco codice 4. Impostazione etichette

Gli elementi dell'app definiti in Code Block 4 sono:

  • QPushButton('') – Il widget QPushButton fornisce un pulsante
  • QComboBox(w) – Il widget QComboBox è un elenco a discesa
  • QLineEdit(w) – Il widget QLineEdit è un input di testo di una riga.
  • QCheckBox – Il widget QCheckBox fornisce una casella di controllo con un'etichetta di testo

Azioni

Ora arriva la parte divertente. Creeremo le azioni e collegheremo i segnali con gli slot.

 @pyqtSlot()
def on_click_loadData():
       bar.setValue(25)
       nomeLista = []
       {...}

       db = str(database.text())
       {...}

       if(name1.isChecked()==True):
       nameList.append("Nome 1")
       {...}
       if(len(elenco dei nomi)>0):
       Nome = str(nameList[randomValueGenerator(len(nameList))-1])

       bar.setValue(50)
       if(str(schema.currentText())=='Schema di test'):
       addTestData(db, 'Test', Nome, {...})
       {...}
       bar.setValue(75)
       bar.setValue(100)

def on_click_deleteData():
       bar.setValue(25)
       db = str(database.text())
       bar.setValue(50)
       if(str(schema.currentText())=='Schema di test'):
       deleteTestData(db, 'Test')
       {...}
       bar.setValue(75)
       bar.setValue(100)

{...}

def randomValueGenerator(len):
       restituisce 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_()

Blocco codice 5. Impostazione etichette

È un pezzo di codice piuttosto lungo. Diamo un'occhiata più da vicino a ciò che abbiamo appena implementato:

  • on_click_loadData() – chiamiamo la funzione addTestData() e ne utilizziamo

btn.clicked.connect() funzione

  • on_click_deleteData() – chiamiamo la funzione deleteTestData() e ne utilizziamo

btn.clicked.connect() funzione

  • randomValueGenerator() – restituisce un valore int casuale dall'intervallo definito
  • btn.clicked.connect() – colleghiamo il segnale con lo slot
  • w.show() – mostra il widget
  • app.exec_() -esegue un'applicazione

Azioni DB

La nostra app necessita di azioni SQL connesse con le azioni dei pulsanti. Utilizzeremo il connettore pyodbc per connetterci a SQL Server DB. Presumo che lo schema DB sia già presente e non sia necessario creare oggetti DB come tabelle ecc.

Aggiungi dati di prova

La funzione addTestData prende i valori dall'interfaccia utente e li passa alla query SQL. Ma esaminiamo l'intero codice:

  • Apertura della connessione al DB di SQL Server definendo dbAddress
  • Impostazione del valore id: se l'id della tabella non è un valore di incremento automatico, è necessario conoscere il prossimo valore di id da utilizzare
  • Definizione di query SQL. Passeremo alcuni valori dall'interfaccia utente.
 importa pyodbc
importa ConfigParser

config = ConfigParser.RawConfigParser()
config.read('../resources/env.properties')
lista = []
login = 'myFancyLogin'

def addTestData(db, schema, Nome {...}):
   Tentativo:
      dbAddress = "Driver={SQL Server};Server=localhost\SQLEXPRESS; 
                   Database="+db+";Connessione_Fidabile=sì; 
                   tu;pwd="
      cnx = pyodbc.connect(dbAddress)
      cursor = cnx.cursor()+schema+"].[candidati] ORDINA PER ID 
            DESCR"
      id = valore restituito (cnx, cursore, id)
      Id = str(id + 1)

      schema = str(schema)

      testQuery = 'SELEZIONA NOME_DB() COME [Database corrente];'
      candidati = "INSERT INTO ["+schema+"].[candidati]      
                    VALUES("+Id+",'"+Nome+"',{...}")"
      returnDBName(cnx, cursore, testQuery)

      lista = [candidati]
      executeQuery(cnx, cursore, elenco)

   tranne pyodbc.Error come e:
      stampa(e)
      print 'errori nella funzione addTestData'
   altro:
      cnx.close()

Blocco codice 6. Aggiungere il metodo dei dati di prova

Elimina i dati del test

L'eliminazione dei dati di test viene gestita dalla funzione deleteTestData(db,schema). Ha solo 2 parametri (db,schema). Significa che vogliamo sgomberare l'intero tavolo senza portare ciò che c'è dentro.

 def deleteTestData(db, schema):
   Tentativo:
      dbAddress = "Driver={SQL Server};Server=localhost\SQLEXPRESS;
                   Database="+db+";Connessione_Fidabile=sì;
                   tu;pwd="
      cnx = pyodbc.connect(dbAddress)
      cursore = cnx.cursor()
 
      schema = str(schema)
 
      testQuery = 'SELEZIONA NOME_DB() COME [Database corrente];'
      candidati = "ELIMINA DA ["+schema+"].[candidati]"
      candidatiProcessed = "ELIMINA DA 
                             ["+schema+"].[candidatesProcessed]"
 
      returnDBName(cnx, cursore, testQuery)
 
      lista = [candidati, candidati Elaborati]
      executeQuery(cnx, cursore, elenco)

   tranne:
      print 'Errori nella funzione deleteTestData'
   altro:
      cnx.close()

Blocco codice 7. Elimina il metodo dei dati di prova

Utili

E alcune funzioni di utilità utilizzate dalle funzioni addTestData() e deleteTestData():

 def executeQuery(cnx, cursor, list):
   per io in lista:
   cursor.execute(i)
   cnx.commit()

def returnDBName(cnx, cursore, dbQuery):
   cursor.execute(dbQuery)
   Valore = cursor.fetchone()
   Valore = Valore[0]
   Valore = str(Valore)

Blocco codice 8. Funzioni utili

Esegui file

Attualmente, possiamo usare il nostro codice se Python è installato e possiamo compilare il codice, ma cosa succede se vogliamo solo avere un file eseguibile? La libreria py2exe permette di creare file eseguibili dal codice Python (Code Block 9):

 dalla configurazione di importazione distutils.core
importa py2exe
      
setup(windows=[nome del file con widget],
   file_dati = file_dati,
   opzioni={ 'py2exe': {
      "include":['sip'],
      "dll_excludes": ['MSVFW32.dll',
      'AVIFIL32.dll',
      'AVICAP32.dll',
      'ADVAPI32.dll',
      'CRYPT32.dll',
      'WLDAP32.dll',
      'MSVCP90.dll']
      }
   })

Blocco codice 9. Creazione del file .exe

Il risultato

Ed ecco il risultato del nostro lavoro. Spero che il tutorial ti sia piaciuto!