$ bash — verificación
python --version
# Output esperado: Python 3.11.x
-weight: 500;">pip --version
# Output esperado: -weight: 500;">pip 23.x.x
bash — verificación
python --version
# Output esperado: Python 3.11.x
-weight: 500;">pip --version
# Output esperado: -weight: 500;">pip 23.x.x
bash — verificación
python --version
# Output esperado: Python 3.11.x
-weight: 500;">pip --version
# Output esperado: -weight: 500;">pip 23.x.x
bash — instalación
-weight: 500;">pip -weight: 500;">install selenium
# Verifica la instalación:
-weight: 500;">pip show selenium
# Deberías ver: Name: selenium, Version: 4.x.x
bash — instalación
-weight: 500;">pip -weight: 500;">install selenium
# Verifica la instalación:
-weight: 500;">pip show selenium
# Deberías ver: Name: selenium, Version: 4.x.x
bash — instalación
-weight: 500;">pip -weight: 500;">install selenium
# Verifica la instalación:
-weight: 500;">pip show selenium
# Deberías ver: Name: selenium, Version: 4.x.x
bash
-weight: 500;">pip -weight: 500;">install webdriver-manager
bash
-weight: 500;">pip -weight: 500;">install webdriver-manager
bash
-weight: 500;">pip -weight: 500;">install webdriver-manager
python — verificación_setup.py
from selenium import webdriver driver = webdriver.Chrome()
driver.get("https://www.selenium.dev")
print(driver.title) # Imprime el título de la página
driver.quit()
# Si ves el título en consola, ¡tu setup funciona!
python — verificación_setup.py
from selenium import webdriver driver = webdriver.Chrome()
driver.get("https://www.selenium.dev")
print(driver.title) # Imprime el título de la página
driver.quit()
# Si ves el título en consola, ¡tu setup funciona!
python — verificación_setup.py
from selenium import webdriver driver = webdriver.Chrome()
driver.get("https://www.selenium.dev")
print(driver.title) # Imprime el título de la página
driver.quit()
# Si ves el título en consola, ¡tu setup funciona!
python — locators_ejemplos.py
from selenium import webdriver
from selenium.webdriver.common.by import By driver = webdriver.Chrome()
driver.get("https://ejemplo.com") # Por ID (el más rápido y confiable cuando existe)
campo_email = driver.find_element(By.ID, "email") # Por Name
campo_pass = driver.find_element(By.NAME, "password") # Por CSS Selector (flexible y legible)
boton = driver.find_element(By.CSS_SELECTOR, "button.btn-primary")
enlace = driver.find_element(By.CSS_SELECTOR, "a[href='/login']") # Por XPath (el más poderoso, úsalo cuando no hay otra opción)
titulo = driver.find_element(By.XPATH, "//h1[@class='title']")
texto = driver.find_element(By.XPATH, "//p[contains(text(),'Bienvenido')]") # Por Link Text (para elementos <a>)
link = driver.find_element(By.LINK_TEXT, "Iniciar Sesión") driver.quit()
python — locators_ejemplos.py
from selenium import webdriver
from selenium.webdriver.common.by import By driver = webdriver.Chrome()
driver.get("https://ejemplo.com") # Por ID (el más rápido y confiable cuando existe)
campo_email = driver.find_element(By.ID, "email") # Por Name
campo_pass = driver.find_element(By.NAME, "password") # Por CSS Selector (flexible y legible)
boton = driver.find_element(By.CSS_SELECTOR, "button.btn-primary")
enlace = driver.find_element(By.CSS_SELECTOR, "a[href='/login']") # Por XPath (el más poderoso, úsalo cuando no hay otra opción)
titulo = driver.find_element(By.XPATH, "//h1[@class='title']")
texto = driver.find_element(By.XPATH, "//p[contains(text(),'Bienvenido')]") # Por Link Text (para elementos <a>)
link = driver.find_element(By.LINK_TEXT, "Iniciar Sesión") driver.quit()
python — locators_ejemplos.py
from selenium import webdriver
from selenium.webdriver.common.by import By driver = webdriver.Chrome()
driver.get("https://ejemplo.com") # Por ID (el más rápido y confiable cuando existe)
campo_email = driver.find_element(By.ID, "email") # Por Name
campo_pass = driver.find_element(By.NAME, "password") # Por CSS Selector (flexible y legible)
boton = driver.find_element(By.CSS_SELECTOR, "button.btn-primary")
enlace = driver.find_element(By.CSS_SELECTOR, "a[href='/login']") # Por XPath (el más poderoso, úsalo cuando no hay otra opción)
titulo = driver.find_element(By.XPATH, "//h1[@class='title']")
texto = driver.find_element(By.XPATH, "//p[contains(text(),'Bienvenido')]") # Por Link Text (para elementos <a>)
link = driver.find_element(By.LINK_TEXT, "Iniciar Sesión") driver.quit()
python — acciones_basicas.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome()
driver.get("https://ejemplo.com") # Click en un botón o enlace
driver.find_element(By.ID, "login-btn").click() # Escribir texto en un campo (SendKeys)
campo = driver.find_element(By.NAME, "username")
campo.clear() # Limpiar primero (buena práctica)
campo.send_keys("mi_usuario") # Enviar formulario con Enter
campo.send_keys(Keys.RETURN) # Obtener texto de un elemento
mensaje = driver.find_element(By.CLASS_NAME, "alert-success")
print(mensaje.text) # Obtener valor de un atributo
url_imagen = driver.find_element(By.TAG_NAME, "img").get_attribute("src") # Navegar
driver.back()
driver.forward()
driver.refresh() # Maximizar ventana
driver.maximize_window() driver.quit()
python — acciones_basicas.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome()
driver.get("https://ejemplo.com") # Click en un botón o enlace
driver.find_element(By.ID, "login-btn").click() # Escribir texto en un campo (SendKeys)
campo = driver.find_element(By.NAME, "username")
campo.clear() # Limpiar primero (buena práctica)
campo.send_keys("mi_usuario") # Enviar formulario con Enter
campo.send_keys(Keys.RETURN) # Obtener texto de un elemento
mensaje = driver.find_element(By.CLASS_NAME, "alert-success")
print(mensaje.text) # Obtener valor de un atributo
url_imagen = driver.find_element(By.TAG_NAME, "img").get_attribute("src") # Navegar
driver.back()
driver.forward()
driver.refresh() # Maximizar ventana
driver.maximize_window() driver.quit()
python — acciones_basicas.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome()
driver.get("https://ejemplo.com") # Click en un botón o enlace
driver.find_element(By.ID, "login-btn").click() # Escribir texto en un campo (SendKeys)
campo = driver.find_element(By.NAME, "username")
campo.clear() # Limpiar primero (buena práctica)
campo.send_keys("mi_usuario") # Enviar formulario con Enter
campo.send_keys(Keys.RETURN) # Obtener texto de un elemento
mensaje = driver.find_element(By.CLASS_NAME, "alert-success")
print(mensaje.text) # Obtener valor de un atributo
url_imagen = driver.find_element(By.TAG_NAME, "img").get_attribute("src") # Navegar
driver.back()
driver.forward()
driver.refresh() # Maximizar ventana
driver.maximize_window() driver.quit()
python — test_login.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time def test_login_exitoso(): # --- Setup --- driver = webdriver.Chrome() driver.maximize_window() driver.get("https://practicetestautomation.com/practice-test-login/") # --- Acción: ingresar credenciales --- driver.find_element(By.ID, "username").send_keys("student") driver.find_element(By.ID, "password").send_keys("Password123") driver.find_element(By.ID, "submit").click() # --- Espera explícita: aguardar elemento post-login --- wait = WebDriverWait(driver, timeout=10) mensaje = wait.until( EC.visibility_of_element_located((By.CLASS_NAME, "post-title")) ) # --- Validación (Assertion) --- assert "Logged In Successfully" in mensaje.text, \ f"Login falló. Texto encontrado: {mensaje.text}" print("✓ Login exitoso verificado") # --- Teardown --- driver.quit() # Ejecutar el test
test_login_exitoso()
python — test_login.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time def test_login_exitoso(): # --- Setup --- driver = webdriver.Chrome() driver.maximize_window() driver.get("https://practicetestautomation.com/practice-test-login/") # --- Acción: ingresar credenciales --- driver.find_element(By.ID, "username").send_keys("student") driver.find_element(By.ID, "password").send_keys("Password123") driver.find_element(By.ID, "submit").click() # --- Espera explícita: aguardar elemento post-login --- wait = WebDriverWait(driver, timeout=10) mensaje = wait.until( EC.visibility_of_element_located((By.CLASS_NAME, "post-title")) ) # --- Validación (Assertion) --- assert "Logged In Successfully" in mensaje.text, \ f"Login falló. Texto encontrado: {mensaje.text}" print("✓ Login exitoso verificado") # --- Teardown --- driver.quit() # Ejecutar el test
test_login_exitoso()
python — test_login.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time def test_login_exitoso(): # --- Setup --- driver = webdriver.Chrome() driver.maximize_window() driver.get("https://practicetestautomation.com/practice-test-login/") # --- Acción: ingresar credenciales --- driver.find_element(By.ID, "username").send_keys("student") driver.find_element(By.ID, "password").send_keys("Password123") driver.find_element(By.ID, "submit").click() # --- Espera explícita: aguardar elemento post-login --- wait = WebDriverWait(driver, timeout=10) mensaje = wait.until( EC.visibility_of_element_located((By.CLASS_NAME, "post-title")) ) # --- Validación (Assertion) --- assert "Logged In Successfully" in mensaje.text, \ f"Login falló. Texto encontrado: {mensaje.text}" print("✓ Login exitoso verificado") # --- Teardown --- driver.quit() # Ejecutar el test
test_login_exitoso()
python — waits_ejemplo.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import FluentWait
from datetime import timedelta # IMPLICIT WAIT (evitar mezclarlo con Explicit Waits)
driver.implicitly_wait(5) # espera hasta 5 seg al buscar elementos # EXPLICIT WAIT (recomendado)
wait = WebDriverWait(driver, timeout=10) # Esperar a que el botón sea clickeable
boton = wait.until(EC.element_to_be_clickable((By.ID, "submit")))
boton.click() # Esperar texto específico en un elemento
wait.until(EC.text_to_be_present_in_element( (By.ID, "-weight: 500;">status"), "Completado"
)) # FLUENT WAIT (polling cada 2 seg, ignora NoSuchElementException)
fluent = FluentWait(driver) \ .with_timeout(timedelta(seconds=30)) \ .polling_every(timedelta(seconds=2)) \ .ignoring(NoSuchElementException) elemento = fluent.until(lambda d: d.find_element(By.ID, "carga-lenta"))
python — waits_ejemplo.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import FluentWait
from datetime import timedelta # IMPLICIT WAIT (evitar mezclarlo con Explicit Waits)
driver.implicitly_wait(5) # espera hasta 5 seg al buscar elementos # EXPLICIT WAIT (recomendado)
wait = WebDriverWait(driver, timeout=10) # Esperar a que el botón sea clickeable
boton = wait.until(EC.element_to_be_clickable((By.ID, "submit")))
boton.click() # Esperar texto específico en un elemento
wait.until(EC.text_to_be_present_in_element( (By.ID, "-weight: 500;">status"), "Completado"
)) # FLUENT WAIT (polling cada 2 seg, ignora NoSuchElementException)
fluent = FluentWait(driver) \ .with_timeout(timedelta(seconds=30)) \ .polling_every(timedelta(seconds=2)) \ .ignoring(NoSuchElementException) elemento = fluent.until(lambda d: d.find_element(By.ID, "carga-lenta"))
python — waits_ejemplo.py
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import FluentWait
from datetime import timedelta # IMPLICIT WAIT (evitar mezclarlo con Explicit Waits)
driver.implicitly_wait(5) # espera hasta 5 seg al buscar elementos # EXPLICIT WAIT (recomendado)
wait = WebDriverWait(driver, timeout=10) # Esperar a que el botón sea clickeable
boton = wait.until(EC.element_to_be_clickable((By.ID, "submit")))
boton.click() # Esperar texto específico en un elemento
wait.until(EC.text_to_be_present_in_element( (By.ID, "-weight: 500;">status"), "Completado"
)) # FLUENT WAIT (polling cada 2 seg, ignora NoSuchElementException)
fluent = FluentWait(driver) \ .with_timeout(timedelta(seconds=30)) \ .polling_every(timedelta(seconds=2)) \ .ignoring(NoSuchElementException) elemento = fluent.until(lambda d: d.find_element(By.ID, "carga-lenta"))
python — pages/login_page.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC class LoginPage: # Locators centralizados: si la UI cambia, solo editas aquí CAMPO_USUARIO = (By.ID, "username") CAMPO_PASSWORD = (By.ID, "password") BOTON_LOGIN = (By.ID, "submit") MENSAJE_ERROR = (By.ID, "error") def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) def ingresar_usuario(self, usuario): campo = self.wait.until(EC.visibility_of_element_located(self.CAMPO_USUARIO)) campo.clear() campo.send_keys(usuario) def ingresar_password(self, password): self.driver.find_element(*self.CAMPO_PASSWORD).send_keys(password) def hacer_click_login(self): self.driver.find_element(*self.BOTON_LOGIN).click() def login(self, usuario, password): # Método de alto nivel: la acción completa de login self.ingresar_usuario(usuario) self.ingresar_password(password) self.hacer_click_login() def obtener_mensaje_error(self): return self.driver.find_element(*self.MENSAJE_ERROR).text
python — pages/login_page.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC class LoginPage: # Locators centralizados: si la UI cambia, solo editas aquí CAMPO_USUARIO = (By.ID, "username") CAMPO_PASSWORD = (By.ID, "password") BOTON_LOGIN = (By.ID, "submit") MENSAJE_ERROR = (By.ID, "error") def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) def ingresar_usuario(self, usuario): campo = self.wait.until(EC.visibility_of_element_located(self.CAMPO_USUARIO)) campo.clear() campo.send_keys(usuario) def ingresar_password(self, password): self.driver.find_element(*self.CAMPO_PASSWORD).send_keys(password) def hacer_click_login(self): self.driver.find_element(*self.BOTON_LOGIN).click() def login(self, usuario, password): # Método de alto nivel: la acción completa de login self.ingresar_usuario(usuario) self.ingresar_password(password) self.hacer_click_login() def obtener_mensaje_error(self): return self.driver.find_element(*self.MENSAJE_ERROR).text
python — pages/login_page.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC class LoginPage: # Locators centralizados: si la UI cambia, solo editas aquí CAMPO_USUARIO = (By.ID, "username") CAMPO_PASSWORD = (By.ID, "password") BOTON_LOGIN = (By.ID, "submit") MENSAJE_ERROR = (By.ID, "error") def __init__(self, driver): self.driver = driver self.wait = WebDriverWait(driver, 10) def ingresar_usuario(self, usuario): campo = self.wait.until(EC.visibility_of_element_located(self.CAMPO_USUARIO)) campo.clear() campo.send_keys(usuario) def ingresar_password(self, password): self.driver.find_element(*self.CAMPO_PASSWORD).send_keys(password) def hacer_click_login(self): self.driver.find_element(*self.BOTON_LOGIN).click() def login(self, usuario, password): # Método de alto nivel: la acción completa de login self.ingresar_usuario(usuario) self.ingresar_password(password) self.hacer_click_login() def obtener_mensaje_error(self): return self.driver.find_element(*self.MENSAJE_ERROR).text
python — tests/test_login.py (usando POM)
from selenium import webdriver
from pages.login_page import LoginPage def test_login_credenciales_validas(): driver = webdriver.Chrome() driver.get("https://practicetestautomation.com/practice-test-login/") # El test es limpio y legible: sin un solo locator login = LoginPage(driver) login.login("student", "Password123") assert "Logged In Successfully" in driver.title or \ driver.current_url != "https://practicetestautomation.com/practice-test-login/" driver.quit() def test_login_credenciales_invalidas(): driver = webdriver.Chrome() driver.get("https://practicetestautomation.com/practice-test-login/") login = LoginPage(driver) login.login("usuario_falso", "clave_incorrecta") error = login.obtener_mensaje_error() assert "Your username is invalid!" in error driver.quit()
python — tests/test_login.py (usando POM)
from selenium import webdriver
from pages.login_page import LoginPage def test_login_credenciales_validas(): driver = webdriver.Chrome() driver.get("https://practicetestautomation.com/practice-test-login/") # El test es limpio y legible: sin un solo locator login = LoginPage(driver) login.login("student", "Password123") assert "Logged In Successfully" in driver.title or \ driver.current_url != "https://practicetestautomation.com/practice-test-login/" driver.quit() def test_login_credenciales_invalidas(): driver = webdriver.Chrome() driver.get("https://practicetestautomation.com/practice-test-login/") login = LoginPage(driver) login.login("usuario_falso", "clave_incorrecta") error = login.obtener_mensaje_error() assert "Your username is invalid!" in error driver.quit()
python — tests/test_login.py (usando POM)
from selenium import webdriver
from pages.login_page import LoginPage def test_login_credenciales_validas(): driver = webdriver.Chrome() driver.get("https://practicetestautomation.com/practice-test-login/") # El test es limpio y legible: sin un solo locator login = LoginPage(driver) login.login("student", "Password123") assert "Logged In Successfully" in driver.title or \ driver.current_url != "https://practicetestautomation.com/practice-test-login/" driver.quit() def test_login_credenciales_invalidas(): driver = webdriver.Chrome() driver.get("https://practicetestautomation.com/practice-test-login/") login = LoginPage(driver) login.login("usuario_falso", "clave_incorrecta") error = login.obtener_mensaje_error() assert "Your username is invalid!" in error driver.quit() - ¿Por qué escribo sobre Selenium? De la frustración a la automatización
- Introducción e Historia
- Características Principales
- Componentes del Ecosistema
- Drivers y Soporte
- Lenguajes Soportados
- Instalación y Configuración
- Beneficios de Automatizar
- Conceptos Clave y Código
- Puntos Críticos de Aprendizaje
- Documentación y Comunidad - 2004: Nacimiento de Selenium Core. Jason Huggins, ingeniero de ThoughtWorks, crea una herramienta interna para automatizar pruebas de la aplicación de gestión de tiempo de su empresa. La llamó "JavaScript Test Runner" y luego la renombró Selenium.
- 2006: Selenium IDE y Selenium RC. Paul Hammant desarrolla Selenium Remote Control (RC), permitiendo ejecutar pruebas en múltiples lenguajes. Simon Stewart comienza a trabajar en WebDriver como proyecto en Google.
- 2008: Unificación histórica. Los equipos de Selenium RC y WebDriver se fusionan. Nace Selenium 2 con WebDriver como componente central. Este fue un punto de inflexión definitivo para la herramienta.
- 2016: Selenium 3. Se lanza como una gran actualización que elimina el antiguo Selenium RC y consolida WebDriver como el núcleo, adoptando además el protocolo W3C WebDriver.
- 2021 - hoy: Selenium 4. La versión actual trae soporte nativo al protocolo W3C, mejor integración con Chrome DevTools Protocol (CDP), soporte para ventanas relativas, y una API más limpia e intuitiva. Esta es la versión que aprenderás en esta guía. - Open Source y Gratuito
Sin costos de licencia. La comunidad global lo mantiene activamente bajo licencia Apache 2.0.
- Multi-navegador
Compatible con Chrome, Firefox, Safari, Edge y Opera. Prueba en todos los entornos de tus usuarios.
- Multi-lenguaje
Escribe tus pruebas en Java, Python, C#, JavaScript, Ruby o Kotlin
- Integración con CI/CD
Se integra con Jenkins, GitHub Actions, GitLab CI, Docker y frameworks como TestNG o JUnit.
- Ejecución en Grid
Distribuye pruebas en múltiples máquinas simultáneamente para reducir tiempo de ejecución.
- Protocolo W3C
Selenium 4 es 100% compatible con el estándar W3C WebDriver, garantizando estabilidad a largo plazo. - Prototipado rápido de pruebas
- Generar código base que luego puedes refinar en WebDriver
- Testers no técnicos que quieren automatizar tareas sencillas - ChromeDriver
Para Google Chrome. Mantenido por el equipo de Chromium.
- GeckoDriver
Para Mozilla Firefox. Mantenido por Mozilla.
- EdgeDriver
Para Microsoft Edge (Chromium). Mantenido por Microsoft.
- SafariDriver
Para Safari. Integrado en macOS, sin descarga adicional. - Linux (Ubuntu, Debian, RHEL)
- Docker Containers - Java
El más popular en empresas. Amplio ecosistema con TestNG y JUnit.
- Python
Sintaxis simple, ideal para principiantes. Muy usado en IA/ML teams.
- C#
Preferido en equipos .NET y Microsoft. Integra con NUnit/MSTest.
- JavaScript
Perfecto para equipos frontend. Funciona con Mocha, Jest, WebdriverIO.
- Ruby
Popular en el ecosistema Rails. Elegante y expresivo. - Ahorro de tiempo masivo: Una suite de regresión que toma 8 horas de forma manual puede ejecutarse en 30 minutos de forma automatizada, liberando tiempo para pruebas exploratorias de mayor valor.
- Precisión y consistencia: Un script automatizado ejecuta exactamente los mismos pasos cada vez, sin el cansancio o descuidos humanos que aparecen en la prueba número 50 del día.
- Reusabilidad del código: Un test escrito una vez puede ejecutarse miles de veces, en múltiples entornos, configuraciones y datos de prueba diferentes.
- Retroalimentación temprana: Integrado en CI/CD, Selenium puede detectar regresiones en minutos después de cada commit, no días después del deployment.
- Cobertura multi-entorno: Con Selenium Grid puedes ejecutar la misma prueba en Chrome, Firefox y Edge simultáneamente, garantizando compatibilidad cross-browser.
- Documentación viva: Los scripts de Selenium, bien escritos, documentan el comportamiento esperado del sistema de forma ejecutable. - selenium.dev/documentation
Documentación oficial. La fuente de verdad para APIs, guías y cambios por versión.
- The Internet (Heroku)
the-internet.herokuapp.com — colección de escenarios de UI complejos para practicar: dropdowns, iframes, alerts, auth.
- r/QualityAssurance
Comunidad activa en Reddit con discusiones sobre herramientas, carrera y mejores prácticas de QA Automation.
- Practice Test Automation
practicetestautomation.com — sitios de práctica diseñados específicamente para aprender Selenium.
- Stack Overflow — selenium
+100,000 preguntas etiquetadas con [selenium]. Si tienes un error, probablemente ya fue resuelto aquí.
- Ministry of Testing
ministryoftesting.com — comunidad global de testers con artículos, cursos y una comunidad muy activa. - No memorices, practica. Selenium se aprende escribiendo código, no leyendo. Después de cada sección, abre tu IDE y escribe los ejemplos desde cero.
- Aprende a usar las DevTools del navegador. F12 es tu mejor aliado. Inspeccionar el HTML, copiar XPaths y depurar selectores CSS es una habilidad diaria en el trabajo de un Automation Tester.
- Nunca uses time.sleep(). Esta línea es la señal de alerta en cualquier code review. Siempre usa WebDriverWait con condiciones explícitas. Tus pruebas serán más rápidas y confiables.
- Siempre llama driver.quit() al final. Diferente a driver.close(), quit() cierra el driver y libera todos los recursos. Usa fixtures de pytest o bloques try/finally para garantizarlo.
- Empieza con un sitio de práctica, no con tu aplicación de trabajo. Practica en sitios como the-internet.herokuapp.com o practicetestautomation.com antes de automatizar en producción.
- Aprende pytest desde el principio. No escribas funciones sueltas. pytest es el framework de testing estándar en Python y te dará estructura, reportes y fixtures desde el día uno.
- Un test debe verificar una sola cosa. Evita los tests "god test" que verifican 15 cosas a la vez. Tests pequeños, enfocados y con nombres descriptivos son más fáciles de depurar cuando fallan.
- Implementa POM desde tu primer proyecto real. Puede parecer overhead al inicio, pero te salvará de semanas de refactoring cuando el equipo de desarrollo cambie la UI. Hazlo hábito desde hoy.
- Usa control de versiones desde el día uno. Tus scripts de automatización son código de producción. Commit frecuente en Git, ramas para nuevas features, pull requests para revisión.
- Lee los errores completos. Un NoSuchElementException, StaleElementReferenceException o TimeoutException tiene una causa específica. Aprende qué significa cada uno; son tus mejores maestros.