Comment créer un chargeur de données de test simple

Publié: 2022-02-23

Introduction

Les projets SQL ne sont pas très populaires parmi la famille des tests. Les ingénieurs de test préfèrent généralement travailler avec l'interface utilisateur ou l'API. Mais il existe de nombreux projets où la logique métier réside dans des bases de données relationnelles ou des entrepôts de données et tôt ou tard, vous devrez effectuer des tests sur DB/DW.

Dans ces projets, de la même manière que dans d'autres, les tests manuels sont toujours une approche valable et nécessitent la préparation de plusieurs configurations de données de test. Cela peut être pénible lorsque vous travaillez avec plusieurs scripts sql de données de test, de nombreux objets de base de données et schémas de base de données. Dans cet article, je vais vous montrer comment créer un chargeur de données de test simple.

Interface utilisateur

Nous utiliserons Python et un serveur SQL comme stockage de données. Commençons par créer une interface utilisateur simple pour une application de bureau. Je suppose que toutes les bibliothèques sont déjà installées, et sinon, alors "pip install [package]"

Fenêtre de réglage

 importer système
importer au hasard
depuis PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
depuis l'import PyQt4.QtGui *
depuis l'importation PyQt4.QtCore *
date et heure d'importation

       app = QApplication(sys.argv)
       w = QWidget()
       w.setWindowTitle('Générateur de données de test')
       w.resize(180, 240)
       w.setFixedSize(800, 460)

       w.setStyleSheet("couleur de fond : blanc ;")

Bloc de code 1. Fenêtre de réglage .

Commencer avec une fenêtre vide comme widget.

Barre de progression

Ajoutons maintenant une barre de progression à notre chargeur de données de test. Il nous dira quand le chargement ou la suppression des données est terminé. La valeur initiale est évidemment fixée à 0.

 classe QProgBar(QProgressBar):

       valeur = 0

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

barre = QBarreProg(w)
barre.redimensionner(320,30)
bar.setValue(0)
barre.move(460,400)

Bloc de code 2. Réglage de la barre de progression

Le bloc de code 2. contient quelques éléments à expliquer :

  • augmenterValeur une méthode qui augmentera la valeur de la barre de progression
  • QProgBar(w) Le widget QProgressBar fournit la barre de progression

Étiquettes

Nous avons besoin d'étiquettes pour les boutons, les listes déroulantes, les champs de saisie, etc.

 lName = QLabel(w)
{...}

lNom.setText("Nom")
lNom.move(60,60)
{...}

Bloc de code 3. Définition des étiquettes

Et l'explication du bloc de code 3.

  • {…} Evidemment, je ne mettrai pas tout le code, donc dorénavant j'utiliserai ce {…} pour renseigner "code continuation here".
  • QLabel(w) -Le widget QLabel fournit un texte

Boutons, cases à cocher et champs de saisie

Passons en revue quelques éléments supplémentaires dans notre application, en commençant par les boutons d'action.

 btnDelete = QPushButton('Supprimer les données de test', w)
btnLoad = QPushButton('Charger les données de test', w)
{...}

schema = QComboBox(w)
schema.addItem("Schéma de test")
schema.move(200,10)
schema.resize(120,25)

base de données = QLineEdit(w)
base de données.move(30, 10)
base de données.resize(120,25)
database.setPlaceholderText("Nom de la base de données")

nom1 = QCheckBox('Nom 1', w)
nom1.move(30, 85)
nom1.setChecked(True)
{...}

Bloc de code 4. Définition des étiquettes

Les éléments d'application définis dans le bloc de code 4 sont :

  • QPushButton('') – Le widget QPushButton fournit un bouton
  • QComboBox(w) – Le widget QComboBox est une liste déroulante
  • QLineEdit(w) – Le widget QLineEdit est une entrée de texte sur une ligne.
  • QCheckBox - Le widget QCheckBox fournit une case à cocher avec une étiquette de texte

Actions

Vient maintenant la partie amusante. Nous allons créer les actions et connecter les signaux aux slots.

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

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

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

       bar.setValue(50)
       if(str(schema.currentText())=='Schéma de test'):
       addTestData(db, 'Test', Nom, {...})
       {...}
       bar.setValue(75)
       bar.setValue(100)

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

{...}

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

Bloc de code 5. Définition des étiquettes

C'est un morceau de code assez long. Regardons de plus près ce que nous venons de mettre en place :

  • on_click_loadData() - nous appelons la fonction addTestData() et utilisons

fonction btn.clicked.connect()

  • on_click_deleteData() - nous appelons la fonction deleteTestData() et utilisons

fonction btn.clicked.connect()

  • randomValueGenerator() - renvoie une valeur int aléatoire à partir de la plage définie
  • btn.clicked.connect() - nous connectons le signal avec l'emplacement
  • w.show() – afficher le widget
  • app.exec_() -exécute une application

Actions BD

Notre application a besoin d'actions SQL liées à des actions de bouton. Nous utiliserons le connecteur pyodbc pour nous connecter à la base de données SQL Server. Je suppose que le schéma de base de données est déjà présent et que nous n'avons pas besoin de créer des objets de base de données tels que des tables, etc.

Ajouter des données de test

La fonction addTestData prend les valeurs de l'interface utilisateur et les transmet à la requête SQL. Mais passons en revue tout le code :

  • Ouverture de la connexion à la base de données SQL Server en définissant dbAddress
  • Définition de la valeur de l'identifiant - si l'identifiant de la table n'est pas un incrément automatique, nous devons connaître la prochaine valeur de l'identifiant à utiliser
  • Définition de la requête SQL. Nous allons transmettre quelques valeurs de l'interface utilisateur.
 importer pyodbc
importer ConfigParser

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

def addTestData(db, schema, Name {...}):
   essayer:
      dbAddress = "Driver={SQL Server} ;Server=localhost\SQLEXPRESS ; 
                   Database="+db+";Trusted_Connection=oui ; 
                   u;pwd="
      cnx = pyodbc.connect(dbAddress)
      curseur = cnx.cursor()+schema+"].[candidats] ORDRE PAR ID 
            DESC"
      id = returnValue(cnx, curseur, id)
      id = str(id + 1)

      schéma = str(schéma)

      testQuery = 'SELECT DB_NAME() AS [Base de données actuelle] ;'
      candidats = "INSÉRER DANS ["+schéma+"].[candidats]      
                    VALEURS("+Id+",'"+Nom+"',{...}")"
      returnDBName(cnx, curseur, testQuery)

      liste = [candidats]
      executeQuery(cnx, curseur, liste)

   sauf pyodbc.Error comme e :
      imprimer(e)
      print 'erreurs dans la fonction addTestData'
   autre:
      cnx.close()

Bloc de code 6. Ajouter une méthode de données de test

Supprimer les données de test

La suppression des données de test est gérée par la fonction deleteTestData(db,schema). Il n'a que 2 paramètres (db, schema). Cela signifie que nous voulons débarrasser toute la table sans emporter ce qu'il y a à l'intérieur.

 def deleteTestData(db, schema):
   essayer:
      dbAddress = "Driver={SQL Server} ;Server=localhost\SQLEXPRESS ;
                   Database="+db+";Trusted_Connection=oui ;
                   u;pwd="
      cnx = pyodbc.connect(dbAddress)
      curseur = cnx.curseur()
 
      schéma = str(schéma)
 
      testQuery = 'SELECT DB_NAME() AS [Base de données actuelle] ;'
      candidats = "SUPPRIMER DE ["+schéma+"].[candidats]"
      candidatsProcessed = "SUPPRIMER DE 
                             ["+schéma+"].[candidatstraités]"
 
      returnDBName(cnx, curseur, testQuery)
 
      liste = [candidats, candidatstraités]
      executeQuery(cnx, curseur, liste)

   à l'exception:
      print 'erreurs dans la fonction deleteTestData'
   autre:
      cnx.close()

Bloc de code 7. Méthode de suppression des données de test

Utilitaires

Et certaines fonctions utils utilisées par les fonctions addTestData() et deleteTestData() :

 def executeQuery(cnx, curseur, liste):
   pour je dans la liste :
   curseur.execute(i)
   cnx.commit()

def returnDBName(cnx, curseur, dbQuery):
   curseur.execute(dbQuery)
   Valeur = curseur.fetchone()
   Valeur = Valeur[0]
   Valeur = chaîne(Valeur)

Bloc de code 8. Fonctions utilitaires

Fichier exe

Actuellement, nous pouvons utiliser notre code si Python est installé et nous pouvons compiler le code, mais que se passe-t-il si nous voulons simplement avoir un fichier exécutable ? La bibliothèque py2exe permet de créer un fichier exécutable à partir de code Python (Code Block 9) :

 à partir de la configuration d'importation distutils.core
importer py2exe
      
setup(windows=[nom du fichier avec le widget],
   data_files = data_files,
   options={ 'py2exe' : {
      "inclut":['sip'],
      "dll_excludes": ['MSVFW32.dll',
      'AVIFIL32.dll',
      'AVICAP32.dll',
      'ADVAPI32.dll',
      'CRYPT32.dll',
      'WLDAP32.dll',
      'MSVCP90.dll']
      }
   })

Bloc de code 9. Création d'un fichier .exe

Le résultat

Et voici le résultat de notre travail. J'espère que vous avez apprécié le tutoriel !