Jak zbudować prosty testowy program do ładowania danych

Opublikowany: 2022-02-23

Wprowadzenie

Projekty SQL nie są zbyt popularne wśród rodziny testerów. Inżynierowie testów zazwyczaj wolą pracować z interfejsem użytkownika lub interfejsem API. Ale jest wiele projektów, w których logika biznesowa leży w relacyjnych bazach danych lub hurtowniach danych i prędzej czy później będziesz musiał przeprowadzić testy na DB/DW.

W tych projektach, podobnie jak w innych, testowanie ręczne jest nadal słusznym podejściem i wymaga przygotowania wielu konfiguracji danych testowych. Może to być bolesne podczas pracy z wieloma skryptami sql danych testowych, wieloma obiektami DB i schematami DB. W tym artykule pokażę, jak zbudować prosty testowy program ładujący dane.

Interfejs użytkownika

Do przechowywania danych będziemy używać Pythona i SQL Server. Najpierw zbudujmy prosty interfejs użytkownika dla aplikacji komputerowej. Zakładam, że wszystkie biblioteki są już zainstalowane, a jeśli nie, to „pip install [pakiet]”

Okno ustawień

 system importu
importuj losowo
z PyQt4.QtCore importuj pyqtSlot,SIGNAL,SLOT
z importu PyQt4.QtGui *
z importu PyQt4.QtCore *
importuj datę i godzinę

       aplikacja = QApplication(sys.argv)
       w = QWidget()
       w.setWindowTitle('Testuj generator danych')
       w.zmiana rozmiaru(180, 240)
       w.setFixedSize(800, 460)

       w.setStyleSheet("kolor-tła: biały;")

Blok kodu 1. Okno ustawień .

Zaczynając od pustego okna jako widżetu.

Pasek postępu

Teraz dodajmy pasek postępu do naszego testowego modułu ładującego dane. Poinformuje nas, kiedy zakończy się ładowanie lub usuwanie danych. Wartość początkowa jest oczywiście ustawiona na 0.

 klasa QProgBar (QProgressBar):

       wartość = 0

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

słupek = QProgBar(w)
bar.zmiana rozmiaru(320,30)
bar.setValue(0)
bar.ruch(460,400)

Blok kodu 2. Ustawianie paska postępu

Code Block 2. zawiera kilka rzeczy do wyjaśnienia:

  • wzrostWartość metoda, która zwiększy wartość paska postępu
  • QProgBar(w) Widżet QProgressBar zapewnia pasek postępu

Etykiety

Potrzebujemy etykiet dla przycisków, list rozwijanych, pól wejściowych itp.

 lNazwa = QEtykieta(w)
{...}

lNazwa.setText("Nazwa")
lNazwa.przenieś(60,60)
{...}

Blok kodu 3. Ustawianie etykiet

Oraz wyjaśnienie bloku kodu 3.

  • {…} Oczywiście nie będę umieszczał całego kodu, więc od teraz będę używał tego {…} do informowania „tutaj kontynuacja kodu”.
  • QLabel(w) — widżet QLabel zawiera tekst

Przyciski, pola wyboru i pola wejściowe

Przejdźmy przez kolejne elementy naszej aplikacji, zaczynając od przycisków akcji.

 btnDelete = QPushButton('Usuń dane testowe', w)
btnLoad = QPushButton('Załaduj dane testowe', w)
{...}

schemat = QComboBox(w)
schema.addItem("Schemat testowy")
schemat.przenieś(200,10)
schema.resize(120,25)

baza danych = QLineEdit(w)
database.move(30, 10)
database.resize(120,25)
database.setPlaceholderText("Nazwa bazy danych")

name1 = QCheckBox('Nazwa 1', w)
nazwa1.przenieś(30, 85)
name1.setChecked (prawda)
{...}

Blok kodu 4. Ustawianie etykiet

Elementy aplikacji zdefiniowane w Code Block 4 to:

  • QPushButton('') – widżet QPushButton udostępnia przycisk
  • QComboBox(w) – widżet QComboBox to lista rozwijana
  • QLineEdit(w) — widżet QLineEdit to jednowierszowe wprowadzanie tekstu.
  • QCheckBox – widżet QCheckBox zawiera pole wyboru z etykietą tekstową

działania

Teraz zaczyna się zabawa. Stworzymy akcje i połączymy sygnały ze szczelinami.

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

       db = str(baza danych.tekst())
       {...}

       if(name1.isChecked()==True):
       nameList.append("Nazwa 1")
       {...}
       if(len(nameList)>0):
       Name = str(nameList[randomValueGenerator(len(nameList))-1])

       bar.setValue(50)
       if(str(schema.currentText())=='Schemat testowy'):
       addTestData(db, 'Test', Nazwa, {...})
       {...}
       bar.setValue(75)
       bar.setValue(100)

def on_click_deleteData():
       bar.setValue(25)
       db = str(baza danych.tekst())
       bar.setValue(50)
       if(str(schema.currentText())=='Schemat testowy'):
       usuńTestData(db, 'Test')
       {...}
       bar.setValue(75)
       bar.setValue(100)

{...}

def generatora wartości losowej(len):
       return losowo.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.pokaż()
app.exec_()

Blok kodu 5. Ustawianie etykiet

To dość długi kawałek kodu. Przyjrzyjmy się bliżej temu, co właśnie wdrożyliśmy:

  • on_click_loadData() – wywołujemy funkcję addTestData() i korzystamy z

funkcja btn.clicked.connect()

  • on_click_deleteData() – wywołujemy funkcję deleteTestData() i korzystamy z

funkcja btn.clicked.connect()

  • randomValueGenerator() – zwraca losową wartość int ze zdefiniowanego zakresu
  • btn.clicked.connect() – łączymy sygnał ze slotem
  • w.show() – pokaż widżet
  • app.exec_() – wykonanie aplikacji

Akcje bazy danych

Nasza aplikacja potrzebuje akcji SQL połączonych z akcjami przycisków. Użyjemy łącznika pyodbc, aby połączyć się z bazą danych SQL Server. Zakładam, że schemat DB jest już obecny i nie musimy tworzyć obiektów DB, takich jak tabele itp.

Dodaj dane testowe

Funkcja addTestData pobiera wartości z interfejsu użytkownika i przekazuje je do zapytania SQL. Ale przejdźmy przez cały kod:

  • Otwieranie połączenia z bazą danych SQL Server poprzez zdefiniowanie dbAddress
  • Ustawienie wartości id – jeśli id ​​tabeli nie jest wartością auto inkrementacji, musimy znać następną wartość id, która ma być użyta
  • Definicja zapytania SQL. Przekażemy kilka wartości z interfejsu użytkownika.
 importuj pyodbc
importuj ConfigParser

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

def addTestData(db, schemat, Nazwa {...}):
   próbować:
      dbAddress = "Sterownik={SQL Server};Server=localhost\SQLEXPRESS; 
                   Database="+db+";Trusted_Connection=tak; 
                   u; hasło=
      cnx = pyodbc.connect(dbAddress)
      kursor = cnx.cursor()+schemat+"].[kandydaci] ORDER BY ID 
            ZPISZ"
      id = returnValue(cnx, kursor, id)
      Identyfikator = str(id + 1)

      schemat = str(schemat)

      testQuery = 'SELECT DB_NAME() AS [Bieżąca baza danych];'
      kandydaci = "INSERT INTO ["+schema+"].[kandydaci]      
                    WARTOŚCI("+Identyfikator+",'"+Nazwa+"',{...}")"
      returnDBName(cnx, kursor, testQuery)

      lista = [kandydaci]
      executeQuery(cnx, kursor, lista)

   z wyjątkiem pyodbc.Błąd jako e:
      druk(e)
      print 'błędy w funkcji addTestData'
   w przeciwnym razie:
      cnx.zamknij()

Blok kodu 6. Dodaj metodę danych testowych

Usuń dane testowe

Usuwanie danych testowych jest obsługiwane przez funkcję deleteTestData(db,schema). Ma tylko 2 parametry (db,schemat). Oznacza to, że chcemy posprzątać cały stół bez noszenia tego, co jest w środku.

 def usuńTestData(db, schemat):
   próbować:
      dbAddress = "Sterownik={SQL Server};Server=localhost\SQLEXPRESS;
                   Database="+db+";Trusted_Connection=tak;
                   u; hasło=
      cnx = pyodbc.connect(dbAddress)
      kursor = cnx.kursor()
 
      schemat = str(schemat)
 
      testQuery = 'SELECT DB_NAME() AS [Bieżąca baza danych];'
      kandydaci = "USUŃ Z ["+schemat+"].[kandydaci]"
      kandydatówPrzetworzony = "USUŃ Z 
                             ["+schemat+"].[kandydaciPrzetworzone]"
 
      returnDBName(cnx, kursor, testQuery)
 
      lista = [kandydaci, kandydaci przetworzone]
      executeQuery(cnx, kursor, lista)

   oprócz:
      print 'błędy w funkcji deleteTestData'
   w przeciwnym razie:
      cnx.zamknij()

Blok kodu 7. Usuń metodę danych testowych

Narzędzia

A niektóre funkcje użytkowe używane przez funkcje addTestData() i deleteTestData():

 def executeQuery(cnx, kursor, lista):
   dla mnie na liście:
   kursor.wykonaj(i)
   cnx.commit()

def returnDBName(cnx, kursor, dbQuery):
   cursor.execute(dbQuery)
   Wartość = cursor.fetchone()
   Wartość = Wartość[0]
   Wartość = str(Wartość)

Blok kodu 8. Funkcje użytkowe

Plik exe

Obecnie możemy użyć naszego kodu, jeśli jest zainstalowany Python i możemy go skompilować, ale co, jeśli chcemy mieć tylko plik wykonywalny? Biblioteka py2exe pozwala na stworzenie pliku wykonywalnego z kodu Pythona (Code Block 9):

 z ustawień importu distutils.core
importuj py2exe
      
setup(windows=[nazwa pliku z widżetem],
   pliki_danych = pliki_danych,
   options={ 'py2exe': {
      "zawiera":['łyk'],
      "dll_excludes": ['MSVFW32.dll',
      'AVIFIL32.dll',
      'AVICAP32.dll',
      'ADVAPI32.dll',
      'CRYPT32.dll',
      'WLDAP32.dll',
      'MSVCP90.dll']
      }
   })

Blok kodu 9. Tworzenie pliku .exe

Wynik

A oto wynik naszej pracy. Mam nadzieję, że podobał Ci się samouczek!