Cinco Modelos de Teste Automatizado em Python
Em testes automatizados, é comum categorizar os scripts de teste em estruturas de framewokr específicas, como o modelo oreintado a palavras-chave. Este artigo descreve cinco abordagens práticas de teste automatizado usando Python: modelo linear, modelo modular orientado a driver, modelo orientado a dados, modelo orientado a palavras-chave e modelo orientado a comportamento.
- Modelo Linear
Neste modelo, scripts sequenciais executam cenários de teste completos. O código a seguir demonstra uma automação simples com Selenium para busca no Google.
import time
from selenium import webdriver
navegador = webdriver.Chrome()
navegador.maximize_window()
navegador.implicitly_wait(20)
navegador.get('https://www.google.com/')
time.sleep(2)
campo_pesquisa = navegador.find_element_by_name('q')
campo_pesquisa.send_keys('automação de testes')
time.sleep(1)
botao_envio = navegador.find_element_by_name('btnK')
botao_envio.click()
time.sleep(3)
navegador.quit()
- Modelo Modular Orientado a Driver
Este modelo promove a reutilização de código ao dividir o projeto em módulos. A estrutura típica inclui diretórios para configuração, dados, drivers, relatórios, testes e utilitários.
- config: contém arquivos de configuração, como base_data.json com URLs de teste.
- data: armazena dados de teste em formatos como JSON ou Excel.
- drivers: guarda executáveis de drivers de navegador.
- report: destina-se a relatórios de execução.
- test: abrange casos de teste, com subdiretórios para etapas, métodos comuns e objetos de página.
Exemplo de caso de teste (teste_pesquisa.py):
import time
import os
import unittest
from selenium import webdriver
from utilitarios.leitor_config import LeitorConfig
from paginas.pagina_pesquisa import PaginaPesquisa
class TestePesquisa(unittest.TestCase):
def setUp(self):
self.navegador = webdriver.Chrome()
self.navegador.maximize_window()
self.navegador.implicitly_wait(25)
def tearDown(self):
self.navegador.quit()
def obter_url(self):
caminho_base = os.path.abspath(os.path.dirname(__file__))
config = LeitorConfig(caminho_base + "/../config/base_data.json")
return config.obter_url()
def teste_pesquisa_valida(self):
url = self.obter_url()
self.navegador.get(url)
time.sleep(1)
pagina = PaginaPesquisa(self.navegador)
pagina.executar_pesquisa('automação de testes')
if __name__ == '__main__':
unittest.main()
Objeto de página (pagina_pesquisa.py):
import time
class PaginaPesquisa:
def __init__(self, driver):
self.driver = driver
def localizar_elementos(self):
self.campo_texto = self.driver.find_element_by_id('kw')
self.botao_pesquisar = self.driver.find_element_by_id('su')
def executar_pesquisa(self, texto):
self.localizar_elementos()
self.campo_texto.send_keys(texto)
time.sleep(1)
self.botao_pesquisar.click()
Executor de testes (executor_principal.py):
import os
import time
import unittest
from utilitarios.gerador_relatorio import RelatorioHTML
class ExecutorTestes:
def coletar_casos(self):
diretorio_atual = os.path.abspath(os.path.dirname(__file__))
caminho_testes = diretorio_atual + '/../testes/'
suite = unittest.defaultTestLoader.discover(caminho_testes, pattern="teste*.py")
return suite
def gerar_relatorio(self, suite, diretorio_saida=None):
if diretorio_saida is None:
diretorio_base = os.path.abspath(os.path.dirname(__file__))
diretorio_saida = diretorio_base + '/../../relatorios/'
timestamp = time.strftime('%Y%m%d%H%M%S')
nome_relatorio = f"relatorio_pesquisa_{timestamp}.html"
caminho_relatorio = os.path.join(diretorio_saida, nome_relatorio)
with open(caminho_relatorio, 'wb') as arquivo:
runner = RelatorioHTML(stream=arquivo, verbosity=2, titulo='Relatório de Pesquisa')
runner.run(suite)
def executar(self, diretorio_saida=None):
suite = self.coletar_casos()
self.gerar_relatorio(suite, diretorio_saida)
if __name__ == '__main__':
ExecutorTestes().executar()
- Modelo Orientado a Dados
Este modelo parametriza testes com dados externos, permitindo execuções repetidas com diferentes conjuntos de entrada.
A estrutura é semelhante ao modelo modular, mas com ênfase em fontes de dados como arquivos Excel ou CSV.
Executor de testes baseado em dados (executar_testes.py):
import os, time, unittest
from utilitarios.gerador_relatorio import RelatorioHTML
class ExecutorDados:
def carregar_testes(self):
caminho_testes = os.getcwd()
suite = unittest.defaultTestLoader.discover(caminho_testes, pattern="Teste*.py")
return suite
def criar_relatorio(self, suite, pasta_saida=None):
if pasta_saida is None:
pasta_saida = os.path.join(os.path.dirname(__file__), 'relatorios')
momento_atual = time.strftime('%Y%m%d_%H%M%S')
arquivo_relatorio = os.path.join(pasta_saida, f"relatorio_dados_{momento_atual}.html")
with open(arquivo_relatorio, 'wb') as relatorio:
runner = RelatorioHTML(stream=relatorio, titulo='Relatório de Testes Orientados a Dados')
runner.run(suite)
def rodar(self, pasta_saida=None):
suite = self.carregar_testes()
self.criar_relatorio(suite, pasta_saida)
if __name__ == "__main__":
ExecutorDados().rodar()
- Modelo Orientado a Palavras-Chave
Neste modelo, ações de teste são definidas por palavras-chave, abstraindo detalhes de implementação. Ferramentas como Robot Framework adotam essa abordagem.
Exemplo de manipulador de ações (manipulador_acoes.py):
from utilitarios.leitor_excel import LeitorExcel
from acoes.acoes_elemento import AcoesElemento
class ManipuladorAcoes:
def __init__(self):
self.acoes_elemento = AcoesElemento()
def executar_acao(self, alvo, operacao, valor=None):
if alvo == "navegador":
return self.acoes_elemento.acao_navegador(operacao, valor)
elif alvo == "tempo":
return self.acoes_elemento.acao_tempo(operacao, valor)
elif alvo:
return self.acoes_elemento.acao_elemento(alvo, operacao, valor)
def rodar_casos(self, arquivo_dados, planilha):
casos = LeitorExcel(arquivo_dados, planilha).obter_todos_casos()
for caso in casos:
self.executar_acao(caso[0], caso[1], caso[2])
if __name__ == '__main__':
manipulador = ManipuladorAcoes()
manipulador.rodar_casos('dados_teste.xlsx', 'pesquisa')
- Modelo Orientado a Comportamento
O BDD (Behavior-Driven Development) utiliza linguagem natural para espceificar testes, facilitando a comunicação entre stakeholders.
Exemplo usando a biblioteca Behave com Python:
import time
from behave import *
@When('eu acesso a página "{url}"')
def etapa_abrir_pagina(contexto, url):
contexto.driver.get(url)
time.sleep(5)
@Then('a página é carregada com sucesso')
def etapa_verificar_pagina(contexto):
titulo = contexto.driver.title
assert "Google" in titulo
@When('eu busco por "{termo}"')
def etapa_pesquisar(contexto, termo):
campo_busca = contexto.driver.find_element_by_name('q')
campo_busca.send_keys(termo)
time.sleep(1)
botao_pesquisar = contexto.driver.find_element_by_name('btnK')
botao_pesquisar.click()
@Then('os resultados contêm "{termo}"')
def etapa_verificar_resultados(contexto, termo):
time.sleep(2)
resultados = contexto.driver.title
assert termo in resultados
Arquivo de comportamento (pesquisa.feature):
Funcionalidade: Busca no Google
Cenário: Realizar uma busca básica
Quando eu acesso a página "https://www.google.com/"
Então a página é carregada com sucesso
Quando eu busco por "automação de testes"
Então os resultados contêm "automação de testes"