Automação de testes em banco de dados — Python + MongoDB

Christian Gonçalves
CWI Software
Published in
3 min readJun 8, 2018

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

#2 Instalação do pandas

É necessária a instalação do pandas.

No terminal, digitar:

pip install pandas

#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.

arquivo __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.

--

--