Como construir um carregador de dados de teste simples
Publicados: 2022-02-23Introdução
Projetos SQL não são muito populares entre a família de testes. Os engenheiros de teste geralmente preferem trabalhar com interface do usuário ou API. Mas há muitos projetos em que a lógica de negócios está em bancos de dados relacionais ou data warehouses e, mais cedo ou mais tarde, você precisará fazer alguns testes em DB/DW.
Nesses projetos, da mesma forma que em outros, o teste manual ainda é uma abordagem válida e requer a preparação de várias configurações de dados de teste. Isso pode ser doloroso ao trabalhar com vários scripts sql de dados de teste, muitos objetos de banco de dados e esquemas de banco de dados. Neste artigo, mostrarei como construir um carregador de dados de teste simples.
Interface de usuário
Usaremos Python e um SQL Server como armazenamento de dados. Em primeiro lugar, vamos construir uma interface de usuário simples para um aplicativo de desktop. Presumo que todas as bibliotecas já estejam instaladas e, se não estiverem, então “pip install [pacote]”
Janela de configuração
sistema de importação importar aleatório de PyQt4.QtCore importar pyqtSlot,SIGNAL,SLOT da importação PyQt4.QtGui * da importação PyQt4.QtCore * importar data e hora app = QApplication(sys.argv) w = QWidget() w.setWindowTitle('Gerador de dados de teste') w.resize(180, 240) w.setFixedSize(800, 460) w.setStyleSheet("cor de fundo: branco;")
Bloco de código 1. Janela de configuração .
Começando com uma janela vazia como um widget.
Barra de progresso
Agora vamos adicionar uma barra de progresso ao nosso carregador de dados de teste. Ele nos informará quando o carregamento ou a exclusão de dados terminar. O valor inicial é obviamente definido como 0.
class QProgBar(QProgressBar): valor = 0 @pyqtSlot() def aumentoValue(progressBar): progressBar.setValue(progressBar.value) progressBar.value = progressBar.value+1 bar = QProgBar(w) bar.resize(320,30) bar.setValue(0) bar.move(460.400)
Bloco de código 2. Configurando a barra de progresso
O Bloco de Código 2 contém algumas coisas a serem explicadas:
- aumentarValor - um método que aumentará o valor da barra de progresso
- QProgBar(w) – O widget QProgressBar fornece a barra de progresso
Rótulos
Precisamos de rótulos para botões, listas suspensas, campos de entrada etc.
lNome = QLabel(w) {...} lNome.setText("Nome") lNome.mover(60,60) {...}
Bloco de código 3. Definindo rótulos
E a explicação do Bloco de Código 3.
- {…} – Obviamente, não vou colocar todo o código, então a partir de agora vou usar este {…} para informar “continuação do código aqui”.
- QLabel(w) -O widget QLabel fornece um texto
Botões, caixas de seleção e campos de entrada
Vamos passar por mais alguns elementos em nosso aplicativo, começando pelos botões de ação.
btnDelete = QPushButton('Excluir dados de teste', w) btnLoad = QPushButton('Carregar dados de teste', w) {...} esquema = QComboBox(w) schema.addItem("Esquema de teste") schema.move(200,10) esquema.resize(120,25) banco de dados = QLineEdit(w) database.move(30, 10) database.resize(120,25) database.setPlaceholderText("Nome do BD") nome1 = QCheckBox('Nome 1', w) nome1.movimento(30, 85) name1.setChecked(True) {...}
Bloco de código 4. Definindo rótulos
Os elementos do aplicativo definidos no Bloco de Código 4 são:
- QPushButton('') – O widget QPushButton fornece um botão
- QComboBox(w) – O widget QComboBox é uma lista suspensa
- QLineEdit(w) – O widget QLineEdit é uma entrada de texto de uma linha.
- QCheckBox – O widget QCheckBox fornece uma caixa de seleção com um rótulo de texto
Ações
Agora vem a parte divertida. Vamos criar as ações e conectar os sinais com os slots.
@pyqtSlot() def on_click_loadData(): bar.setValue(25) NomeLista = [] {...} db = str(database.text()) {...} if(name1.isChecked()==True): nameList.append("Nome 1") {...} if(len(nomeLista)>0): Nome = str(nameList[randomValueGenerator(len(nameList))-1]) bar.setValue(50) if(str(schema.currentText())=='Esquema de teste'): addTestData(db, 'Teste', 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())=='Esquema de teste'): deleteTestData(db, 'Teste') {...} 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_()
Bloco de código 5. Definindo rótulos

É um pedaço de código bem longo. Vamos dar uma olhada no que acabamos de implementar:
- on_click_loadData() – chamamos a função addTestData() e fazemos uso de
função btn.clicked.connect()
- on_click_deleteData() – chamamos a função deleteTestData() e fazemos uso de
função btn.clicked.connect()
- randomValueGenerator() – retorna valor int aleatório do intervalo definido
- btn.clicked.connect() – conectamos sinal com slot
- w.show() – mostra widget
- app.exec_() -executa uma aplicação
Ações de banco de dados
Nosso aplicativo precisa de ações SQL conectadas a ações de botão. Usaremos o conector pyodbc para conectar ao banco de dados SQL Server. Suponho que o esquema de banco de dados já esteja presente e não precisamos criar objetos de banco de dados como tabelas etc.
Adicionar dados de teste
A função addTestData obtém valores da interface do usuário e os passa para a consulta SQL. Mas vamos passar por todo o código:
- Abrindo a conexão com o banco de dados SQL Server definindo dbAddress
- Configurando o valor do id – se o id da tabela não for de incremento automático, precisamos saber o próximo valor do id a ser usado
- Definição de consulta SQL. Passaremos alguns valores da interface do usuário.
importar pyodbc importar ConfigParser config = ConfigParser.RawConfigParser() config.read('../resources/env.properties') lista = [] login = 'myFancyLogin' def addTestData(db, esquema, Nome {...}): tentar: dbAddress = "Driver={SQL Server};Servidor=localhost\SQLEXPRESS; Banco de dados="+db+";Trusted_Connection=sim; u;pwd=" cnx = pyodbc.connect(dbAddress) cursor = cnx.cursor()+schema+"].[candidatos] ORDER BY ID DESC" id = returnValue(cnx, cursor, id) Id = str(id + 1) esquema = str(esquema) testQuery = 'SELECT DB_NAME() AS [Banco de Dados Atual];' candidatos = "INSERIR EM ["+esquema+"].[candidatos] VALUES("+Id+",'"+Nome+"',{...}")" returnDBName(cnx, cursor, testQuery) lista = [candidatos] executeQuery(cnx, cursor, lista) exceto pyodbc.Error como e: imprimir(e) print 'erros na função addTestData' senão: cnx.close()
Bloco de código 6. Adicionar método de dados de teste
Excluir dados de teste
A exclusão de dados de teste é tratada pela função deleteTestData(db,schema). Tem apenas 2 parâmetros (db,schema). Isso significa que queremos limpar a mesa inteira sem carregar o que está dentro.
def deleteTestData(db, esquema): tentar: dbAddress = "Driver={SQL Server};Servidor=localhost\SQLEXPRESS; Banco de dados="+db+";Trusted_Connection=sim; u;pwd=" cnx = pyodbc.connect(dbAddress) cursor = cnx.cursor() esquema = str(esquema) testQuery = 'SELECT DB_NAME() AS [Banco de Dados Atual];' candidatos = "EXCLUIR DE ["+esquema+"].[candidatos]" candidatosProcessado = "EXCLUIR DE ["+esquema+"].[candidatosProcessado]" returnDBName(cnx, cursor, testQuery) list = [candidatos, candidatosProcessado] executeQuery(cnx, cursor, lista) exceto: print 'erros na função deleteTestData' senão: cnx.close()
Bloco de código 7. Excluir método de dados de teste
Útil
E algumas funções utils usadas pelas funções addTestData() e deleteTestData():
def executeQuery(cnx, cursor, list): para i na lista: cursor.execute(i) cnx.commit() def returnDBName(cnx, cursor, dbQuery): cursor.execute(dbQuery) Valor = cursor.fetchone() Valor = Valor[0] Valor = str(Valor)
Bloco de Código 8. Funções Util
Arquivo exe
Atualmente, podemos usar nosso código se o Python estiver instalado e pudermos compilar o código, mas e se quisermos apenas ter um arquivo executável? A biblioteca py2exe permite criar um arquivo executável a partir do código Python (Code Block 9):
da configuração de importação do distutils.core importar py2exe setup(windows=[nome do arquivo com widget], data_files = data_files, options={ 'py2exe': { "inclui":['sip'], "dll_excludes": ['MSVFW32.dll', 'AVIFIL32.dll', 'AVICAP32.dll', 'ADVAPI32.dll', 'CRYPT32.dll', 'WLDAP32.dll', 'MSVCP90.dll'] } })
Bloco de código 9. Criando arquivo .exe
O resultado
E aqui está o resultado do nosso trabalho. Espero que tenham gostado do tutorial!
