Automação de testes em banco de dados — Python + MongoDB
Criação de um cenário de teste automatizado em Python com o framework unittest para validar informações no MongoDB.
Requisitos:
- Python 3.6 ;
- PyCharm ou outra IDE para Python;
- pymongo instalado;
- pandas instalado.
#1 Instalação do pymongo
É necessária a instalação do driver de conexão com o MongoDB.
No terminal, digitar:
$ python -m pip install pymongo
#3 Construção da classe python
Para o Python reconhecer o diretório como uma package, é necessário que dentro dele possua um arquivo vazio com o nome __init__.py.
Dentro da classe, realiza-se a importação do módulo de conexão com o MongoDB (pymongo):
from pymongo import MongoClient
Instancia-se a classe:
class MongoAutomation:
Cria-se a conexão com o MongoDB. Neste exemplo está sendo utilizada uma base local com um banco denominado cwi-automation, para isso é necessária a instalação local do MongoDB. Mas pode-se acessar outras instâncias do banco, apenas alterando a connection string.
def connect_database(self):
self.db_client = MongoClient('localhost', 27017)
self.db = self.db_client.cwi_automation
Agora faz-se necessária a leitura da(s) collection(s) que deseja-se validar informações. Neste exemplo faremos uma comparação dos dados entre duas collections utilizando o módulo python chamado pandas. A comparação também pode ser feita através de um simples loop for, porém é menos performática para grandes volumes de documentos.
def read_collections(self):
self.collection1 = self.db[collection1].find()
self.collection2 = self.db[collection2].find()
Realiza-se a importação do pandas:
import pandas as pd
No link abaixo, a documentação referente a DataFrame do pandas:
Transforma-se os dados das variáveis collection1 e collection2 em dataframes, e realiza-se um agrupamento com o comando concat([param1, param2]). Após isto, efetua-se a comparação, gerando um novo dataframe. Caso ambas as collections sejam iguais, o dataframe gerado deve estar vazio.
def transform_in_dataframe(self):
df1 = pd.DataFrame.from_records(self.collection1)
df2 = pd.DataFrame.from_records(self.collection2)
self.df_grouped = pd.concat([df1, df2])
def compare_collections(self):
column_headers = list(self.df_grouped.columns.values)
column_headers.remove('_id')
self.df_final = self.df_grouped.drop_duplicates(column_headers, keep=False)
Neste exemplo citado, está sendo removida a informação referente a _id que o MongoDB gera, desconsiderando assim _ids diferentes.
Até este ponto, a classe deve estar assim:
import pandas as pd
from pymongo import MongoClient
class MongoAutomation:
def connect_database(self):
self.db_client = MongoClient('localhost', 27017)
self.db = self.db_client.cwi_automation
def read_collections(self):
self.collection1 = self.db[collection1].find()
self.collection2 = self.db[collection2].find()
def transform_in_dataframe(self):
df1 = pd.DataFrame.from_records(self.collection1)
df2 = pd.DataFrame.from_records(self.collection2)
self.df_grouped = pd.concat([df1, df2])
def compare_collections(self):
column_headers = list(self.df_grouped.columns.values)
column_headers.remove('_id')
self.df_final = self.df_grouped.drop_duplicates(column_headers, keep=False)
#4 Criação do Test Case:
Cria-se um novo python file e importa-se o módulo unittest e a classe onde estão os métodos criados anteriormente:
import unittest
import src.compare_collections
Instancia-se a classe de teste:
class TestsCompareCollections(unittest.TestCase):
Utilizando as TestFixtures do unittest, cria-se o setUp() e o tearDown(), que serão executados antes e depois da execução do cenário, respectivamente. Neste exemplo o setUp() apenas instancia a classe com os métodos, enquanto o tearDown() finaliza a conexão com o MongoClient.
def setUp(self):
self.obj = src.compare_collections.CompareCollections()def tearDown(self):
self.obj.db_client.close()
Feito isso, cria-se o cenário de teste:
def test_compare_collections(self):
"""Comparacao entre duas collections do MongoDB"""
self.obj.connect_database()
self.obj.read_collections()
self.obj.transform_in_dataframe()
self.obj.compare_collections()
O python identificará que este método é um cenário de teste através do prefixo test na descrição (test_compare_collections).
Desta forma, a classe de teste deverá estar assim:
import unittest
import src.compare_collections
class TestsCompareCollections(unittest.TestCase):
def setUp(self):
self.obj = src.compare_collections.CompareCollections()
def test_compare_collections(self):
"""Comparacao entre duas collections do MongoDB"""
self.obj.connect_database()
self.obj.read_collections()
self.obj.transform_in_dataframe()
self.obj.compare_collections()
def tearDown(self):
self.obj.db_client.close()
if __name__ == '__main__':
unittest.main()
Cenário de teste criado, a execução pode ser feita através da IDE ou pelo terminal.
Obs: Por ser apenas um exemplo bem simplificado, não foram contemplados asserts, logs e outras validações necessárias em um teste automatizado. Todas essas informações estão disponíveis na documentação do unittest e também na documentação do python 3.
Para dúvidas, críticas, sugestões, deixo meu perfil para contato.