O padrão Page Object Model (POM) é uma das melhores práticas para a criação de suítes de testes automatizados, pois promove a reutilização de código e facilita a manutenção. Nesta estrutura, organizamos o projeto de forma modular, separando a lógica de negócio, os seletores de elementos e a configuração do ambietne.
Estrutura de Diretórios
Para um framework escalável, a organização das pastas deve ser intuitiva. Abaixo está a disposição sugerida para os módulos do projeto:
- data/: Armazena arquivos de configuração (INI, Excel, JSON).
- public/pages/: Contém as classes que representam as páginas da aplicação.
- public/utils/: Classes utilitárias (leitores de arquivos, conexões de banco de dados).
- report/: Local onde os relatórios de execução são gerados.
- testcase/: Scripts de teste propriamente ditos.
- run/: Scripts para execução em lote ou integração contínua.
Gerenciamento Dinâmico de Caminhos
Para evitar problemas de caminhos absolutos entre diferentse ambientes (máquinas de desenvolvedores vs. servidores de CI), utilizamos a biblioteca pathlib para mapear a raiz do projeto de forma dinâmica.
from pathlib import Path
# Define a raiz do projeto com base na localização deste arquivo
PROJ_ROOT = Path(__file__).resolve().parent.parent
# Mapeamento de diretórios principais
DIR_DATA = PROJ_ROOT / "data"
DIR_PAGES = PROJ_ROOT / "public" / "pages"
DIR_UTILS = PROJ_ROOT / "public" / "utils"
DIR_REPORTS = PROJ_ROOT / "report"
DIR_TESTS = PROJ_ROOT / "testcase"
DIR_RUNNER = PROJ_ROOT / "run"
Configuração de Dados com Arquivos INI
O uso de arquivos .ini permite que parâmetros como URLs de ambiente e credenciais de teste sejam alterados sem a necessidade de modificar o código-fonte.
[environment]
base_url = http://exemplo.com/login
timeout = 30
[admin_user]
user = administrador
pass = senha_segura_123
[database_config]
db_host = 127.0.0.1
db_port = 5432
db_name = homolog_db
Desenvolvimento do Utilitário de Leitura
Abaixo, implementamos uma classe utilitária utilizando o módulo configparser para extrair informações do arquivo de configuração de forma simplificada.
import configparser
import os
class ConfigHandler:
def __init__(self, target_file):
"""
Inicializa o leitor de configurações carregando o arquivo especificado.
"""
self.cfg = configparser.ConfigParser()
if os.path.exists(target_file):
self.cfg.read(target_file, encoding='utf-8')
else:
raise FileNotFoundError(f"Arquivo de configuração não encontrado: {target_file}")
def get_setting(self, section, key):
"""
Recupera um valor específico dentro de uma seção.
"""
try:
return self.cfg.get(section, key)
except (configparser.NoSectionError, configparser.NoOptionError) as err:
print(f"Erro ao buscar configuração: {err}")
return None
# Exemplo de utilização da classe
if __name__ == "__main__":
path_to_ini = os.path.join(os.getcwd(), "data", "config.ini")
loader = ConfigHandler(path_to_ini)
url_app = loader.get_setting("environment", "base_url")
print(f"URL carregada: {url_app}")
Esta abordagem centraliza a gestão de dados e caminhos, tornando o framework robusto. Ao separar a configuração da lógica de teste, garantimos que mudanças na infraestrutura ou nos dados de teste tenham um impacto mínimo nos scripts de automação existentes.