Qué es Selenium Grid y para qué sirve
Selenium Grid es un componente de la suite Selenium que permite ejecutar pruebas en paralelo sobre múltiples máquinas y navegadores simultáneamente. Su principal ventaja es reducir drásticamente el tiempo total de ejecución de una suite de pruebas grande.
Casos de uso principales:
- Ejecutar 100 pruebas en 10 nodos (cada nodo ejecuta 10 pruebas) en lugar de las 100 secuencialmente
- Probar en múltiples navegadores (Chrome, Firefox, Edge) al mismo tiempo
- Probar en múltiples sistemas operativos (Windows, Linux, macOS)
- Integrar pruebas en pipelines CI/CD con recursos elásticos
Arquitectura de Selenium Grid 4
Selenium Grid 4 reemplazó la arquitectura Hub/Node de versiones anteriores con una arquitectura más modular:
| Componente | Función | |-----------|---------| | Router | Punto de entrada. Dirige peticiones a Session Map o Distribuidor | | Session Map | Registra qué sesión corre en qué nodo | | Distribuidor | Asigna nuevas sesiones al nodo más adecuado disponible | | Node | Ejecuta los tests en los navegadores instalados | | Event Bus | Comunicación interna entre componentes |
En modo standalone, todos estos componentes se ejecutan en un único proceso Java, ideal para desarrollo local.
Selenium Grid en modo standalone
Descarga e inicio
# Descargar Selenium Server (incluye Grid)
# Versión más reciente: https://www.selenium.dev/downloads/
wget https://github.com/SeleniumHQ/selenium/releases/download/selenium-4.26.0/selenium-server-4.26.0.jar
# Iniciar en modo standalone (todos los componentes en un proceso)
java -jar selenium-server-4.26.0.jar standalone
# Con configuración adicional
java -jar selenium-server-4.26.0.jar standalone \
--port 4444 \
--max-sessions 4 \
--session-timeout 300
Acceder a la interfaz web: http://localhost:4444
Conectar desde Java con RemoteWebDriver
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.URL;
public class EjemploGrid {
public static void main(String[] args) throws Exception {
// URL del Selenium Grid
URL gridUrl = new URL("http://localhost:4444");
// Capacidades del navegador
ChromeOptions options = new ChromeOptions();
options.addArguments("--no-sandbox");
options.addArguments("--disable-dev-shm-usage");
// Conectar al Grid
WebDriver driver = new RemoteWebDriver(gridUrl, options);
try {
driver.get("https://www.selenium.dev");
System.out.println("Título: " + driver.getTitle());
} finally {
driver.quit();
}
}
}
Selenium Grid con Docker Compose
Docker Compose es la forma más sencilla de desplegar un Grid completo con múltiples nodos para diferentes navegadores.
docker-compose.yml para Selenium Grid 4
# docker-compose.yml
version: "3.8"
services:
# Selenium Grid Hub (Router + Distribuidor + Session Map)
selenium-hub:
image: selenium/hub:4.26.0
container_name: selenium-hub
ports:
- "4444:4444" # Interfaz web y API
- "4442:4442" # Event Bus publish
- "4443:4443" # Event Bus subscribe
environment:
- GRID_MAX_SESSION=16
- GRID_TIMEOUT=300
- GRID_SESSION_TIMEOUT=300
# Nodo con Chrome
node-chrome:
image: selenium/node-chrome:4.26.0
container_name: node-chrome
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=4
- SE_NODE_OVERRIDE_MAX_SESSIONS=true
volumes:
- /dev/shm:/dev/shm # Memoria compartida para Chrome
shm_size: "2gb"
# Nodo con Firefox
node-firefox:
image: selenium/node-firefox:4.26.0
container_name: node-firefox
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=4
volumes:
- /dev/shm:/dev/shm
# Nodo con Edge
node-edge:
image: selenium/node-edge:4.26.0
container_name: node-edge
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_MAX_SESSIONS=2
volumes:
- /dev/shm:/dev/shm
Iniciar el Grid:
# Iniciar todos los contenedores
docker-compose up -d
# Ver el estado de los contenedores
docker-compose ps
# Ver los logs del hub
docker-compose logs -f selenium-hub
# Parar el Grid
docker-compose down
Grid con VNC para debugging visual
Para ver lo que ejecuta cada nodo (útil durante el desarrollo):
# Nodo Chrome con VNC y noVNC
node-chrome-debug:
image: selenium/node-chrome:4.26.0
container_name: node-chrome-debug
depends_on:
- selenium-hub
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_START_VNC=true # Iniciar servidor VNC
- SE_START_NO_VNC=true # Iniciar noVNC (acceso web)
- SE_NO_VNC_PORT=7900 # Puerto para noVNC
ports:
- "7900:7900" # Acceder en http://localhost:7900 (contraseña: secret)
volumes:
- /dev/shm:/dev/shm
Ejecutar pruebas en paralelo con JUnit 5
// src/test/java/grid/SeleniumGridTest.java
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.remote.AbstractDriverOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
class SeleniumGridTest {
private static final String GRID_URL = "http://localhost:4444";
private WebDriver driver;
static Stream<AbstractDriverOptions<?>> proveedorOpciones() {
ChromeOptions chrome = new ChromeOptions();
chrome.addArguments("--no-sandbox", "--disable-dev-shm-usage");
FirefoxOptions firefox = new FirefoxOptions();
EdgeOptions edge = new EdgeOptions();
edge.addArguments("--no-sandbox");
return Stream.of(chrome, firefox, edge);
}
@BeforeEach
void setUp() {
// El driver se inicializa en cada test parametrizado
}
@AfterEach
void tearDown() {
if (driver != null) {
driver.quit();
}
}
@ParameterizedTest(name = "Navegador: {0}")
@MethodSource("proveedorOpciones")
void debeMostrarTituloCorrectoEnTodosLosNavegadores(
AbstractDriverOptions<?> options) throws MalformedURLException {
driver = new RemoteWebDriver(new URL(GRID_URL), options);
driver.manage().window().maximize();
driver.get("https://www.selenium.dev");
assertTrue(
driver.getTitle().contains("Selenium"),
"El título debe contener 'Selenium' en: " + options.getBrowserName()
);
}
}
Configuración de JUnit 5 para ejecución paralela
# src/test/resources/junit-platform.properties
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
junit.jupiter.execution.parallel.mode.classes.default = concurrent
junit.jupiter.execution.parallel.config.strategy = dynamic
junit.jupiter.execution.parallel.config.dynamic.factor = 3
Monitorización de Selenium Grid
Interfaz web
Accede a http://localhost:4444 para ver:
- Nodos registrados y su estado
- Sesiones activas en cada nodo
- Capacidades disponibles
API GraphQL
Selenium Grid 4 expone una API GraphQL en http://localhost:4444/graphql:
# Consultar el estado del Grid
curl -X POST http://localhost:4444/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "{ grid { maxSession, nodeCount } nodes { id, status, maxSession, slotCount } }"
}'
Endpoint de status
# Estado del Grid en JSON
curl http://localhost:4444/status | python3 -m json.tool
Consideraciones para CI/CD
# .github/workflows/selenium-grid.yml (ejemplo para GitHub Actions)
name: Selenium Grid Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
selenium-hub:
image: selenium/hub:4.26.0
ports:
- 4444:4444
node-chrome:
image: selenium/node-chrome:4.26.0
options: --shm-size=2gb
env:
SE_EVENT_BUS_HOST: selenium-hub
SE_EVENT_BUS_PUBLISH_PORT: 4442
SE_EVENT_BUS_SUBSCRIBE_PORT: 4443
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"
- name: Wait for Grid to be ready
run: |
timeout 60 bash -c 'until curl -s http://localhost:4444/status | grep -q "ready.*true"; do sleep 2; done'
- name: Run tests
run: mvn test -DGRID_URL=http://localhost:4444
Fuentes y referencias
Documentación oficial y recursos externos para profundizar en Selenium
Documentación oficial de Selenium
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Selenium es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Selenium
Explora más contenido relacionado con Selenium y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
Comprender la arquitectura de Selenium Grid 4 con Router, Distribuidor, Node y Session Map. Configurar Selenium Grid en modo standalone para desarrollo local. Desplegar Selenium Grid con múltiples nodos usando Docker Compose. Conectar RemoteWebDriver a Selenium Grid para ejecutar pruebas distribuidas. Monitorizar la infraestructura de Grid a través de la interfaz web y GraphQL. Ejecutar pruebas en paralelo con JUnit 5 sobre Selenium Grid.