Singleton WebDriver (Singleton WebDriver)
Один экземпляр WebDriver создаётся как статический синглтон и используется всеми тестами в JVM. Браузерная сессия никогда не пересоздаётся между тестами.
Симптомы
- Статическое поле
private static WebDriver driverв базовом классе или утилите - Метод
getDriver()с паттерном «ленивая инициализация» черезif (driver == null) - Один экземпляр
ChromeDriver/FirefoxDriverна весь тест-ран -
@BeforeAll static void setUp()с созданием одного driver для всего класса
Причины возникновения
- Создание WebDriver кажется «дорогим» — синглтон экономит время запуска
- Паттерн синглтона знаком из продакшн-кода и переносится в тесты без адаптации
- Нет понимания жизненного цикла браузерной сессии и изоляции тестов
- Первый рабочий прототип использовал статическое поле, и никто его не рефакторил
Почему это проблема
- Нельзя запускать параллельно: несколько потоков используют один driver → гонки, случайные падения
- Накопление состояния: cookies, localStorage, открытые диалоги от теста A влияют на тест B
-
Утечки сессий: если тест упал раньше
quit()— driver завис, процесс браузера не завершён - Один браузер: нельзя тестировать разные профили, языки или разрешения экрана одновременно
- Сложная очистка: нужно помнить, что именно «замусорил» предыдущий тест
Решение
ThreadLocal<WebDriver> — каждый поток получает свой driver:
// ❌
public static WebDriver getDriver() {
if (driver == null) driver = new ChromeDriver();
return driver;
}
// ✅
private static final ThreadLocal<WebDriver> driverHolder = new ThreadLocal<>();
public static WebDriver getDriver() { return driverHolder.get(); }
public static void initDriver() { driverHolder.set(new ChromeDriver()); }
public static void quitDriver() {
driverHolder.get().quit();
driverHolder.remove();
}