Configuração Inicial
Para iniciar a automação de testes web com Python, recomenda-se o uso do ambiente de desenvolvimento PyCharm e a biblioteca Selenium (versão 4.14.0 ou superior). O processo de inspeção de elementos é fundamental: basta clicar com o botão direito em qualquer componente de uma página web, selecionar "Inspecionar" e navegar pela aba "Elements" para visualizar o código HTML.
Abaixo, o código base para inicializar o driver e acessar uma URL:
from selenium import webdriver
from selenium.webdriver.common.by import By
# Inicialização do navegador
navegador = webdriver.Chrome()
# Definindo o destino (URL remota ou arquivo local)
url_alvo = "https://www.google.com"
navegador.get(url_alvo)
Localização de Elementos
O Selenium oferece diversas estratégias para capturar elementos na árvore DOM. Aqui estão as principais abordagens utilizando o método find_element:
- ID:
navegador.find_element(By.ID, "usuario_login").send_keys("admin") - Namme:
navegador.find_element(By.NAME, "senha_campo").send_keys("12345") - Class Name:
navegador.find_element(By.CLASS_NAME, "btn-principal").click() - Tag Name:
navegador.find_element(By.TAG_NAME, "input") - Link Text:
navegador.find_element(By.LINK_TEXT, "Esqueci minha senha").click() - Partial Link Text:
navegador.find_element(By.PARTIAL_LINK_TEXT, "Esqueci").click() - XPath:
navegador.find_element(By.XPATH, "//div[@id='container']/input") - CSS Selector:
navegador.find_element(By.CSS_SELECTOR, ".container > #login")
Captura de Múltiplos Elementos
Quando múltiplos elementos compartilham a mesma classe ou tag, utilizamos find_elements, que retorna uma lista:
itens = navegador.find_elements(By.CLASS_NAME, "item-lista")
itens[0].send_keys("Primeiro item")
Gerenciamento de Tempo e Esperas
O controle de tempo é essencial para lidar com o carregamento de páginas assíncronas:
import time
# Espera forçada (não recomendada para produção)
time.sleep(2)
# Espera implícita (configura um tempo máximo global)
navegador.implicitly_wait(10)
Interações Avançadas: Mouse e Teclado
Para ações complexas como cliques duplos ou atalhos de teclado, utilizamos as classes ActionChains e Keys.
Ações de Mouse
from selenium.webdriver import ActionChains
elemento_alvo = navegador.find_element(By.ID, "menu-contexto")
acoes = ActionChains(navegador)
# Clique duplo
acoes.double_click(elemento_alvo).perform()
# Clique com botão direito
acoes.context_click(elemento_alvo).perform()
Comandos de Teclado
from selenium.webdriver.common.keys import Keys
campo_texto = navegador.find_element(By.ID, "busca")
campo_texto.send_keys("Automação")
# Selecionar tudo e apagar
campo_texto.send_keys(Keys.CONTROL, 'a')
campo_texto.send_keys(Keys.BACK_SPACE)
# Pressionar Enter
campo_texto.send_keys(Keys.ENTER)
Manipulação de Janelas e Alertas
Interagir com diálogos do sistema e múltiplas abas exige a troca de contexto do driver:
# Lidar com Alertas (JavaScript)
alerta = navegador.switch_to.alert
print(alerta.text)
alerta.accept() # Confirma o alerta
# Alternar entre janelas/abas
janelas = navegador.window_handles
navegador.switch_to.window(janelas[1]) # Vai para a segunda aba
Execução de Scripts e Upload de Arquivos
Para manipular o DOM diretamente ou rolar a página, o método execute_script é utilizado:
# Rolagem de página via JavaScript
navegador.execute_script("window.scrollTo(0, 1000)")
# Upload de arquivos (enviando o caminho do arquivo para um input do tipo file)
input_file = navegador.find_element(By.ID, "upload-id")
input_file.send_keys("C:\\documentos\\teste.txt")
Estrutura de Testes com Unittest
O framework unittest permite organizar os testes em classes, faciiltando a manutenção e execução em massa.
import unittest
from selenium import webdriver
class TesteSistemaLogin(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
def setUp(self):
self.driver.get("https://exemplo.com/login")
def test_login_sucesso(self):
# Lógica do teste
self.assertEqual(self.driver.title, "Dashboard")
def tearDown(self):
print("Teste finalizado.")
@classmethod
def tearDownClass(cls):
cls.driver.quit()
if __name__ == "__main__":
unittest.main()
Testes Baseados em Dados (DDT)
Para rodar o mesmo cenário com diferentes entradas, a biblioteca ddt é a solução ideal:
import unittest
from ddt import ddt, data, unpack
@ddt
class TesteCalculos(unittest.TestCase):
@data((5, 5, 10), (10, 20, 30))
@unpack
def test_soma(self, val1, val2, esperado):
resultado = val1 + val2
self.assertEqual(resultado, esperado)
Leitura de Arquivos CSV
Muitas vezes os dados de teste residem em planilhas CSV. Veja como processá-los removendo o cabeçalho:
import csv
def carregar_dados_csv(caminho):
dados = []
with open(caminho, 'r', encoding='utf-8') as f:
leitor = csv.reader(f)
for linha in leitor:
dados.append(linha)
return dados[1:] # Remove o cabeçalho
Tabela de Referência de Ações
| Comando | Descrição |
|---|---|
click() |
Clique simples no elemento. |
send_keys() |
Insere texto ou comandos de teclado. |
get_screenshot_as_file(path) |
Salva uma captura de tela. |
current_window_handle |
Obtém o ID da janela ativa. |
assertEqual(a, b) |
Verifica se dois valores são iguais. |