You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pytest-xdist并行执行Selenium测试时,仅启动单Chrome实例多标签的问题

问题:pytest-xdist并行执行Selenium测试时无法启动独立Chrome实例

我编写了3个Selenium测试用例,希望通过pytest-xdist并行执行,每个测试用例对应启动一个独立的Chrome实例,但实际只启动了一个实例并打开3个标签页,仅第一个标签页完成页面导航,其余标签页为空。

测试代码如下:

from time import sleep

from selenium import webdriver
from selenium.webdriver import ChromeOptions

port = 4444
command_executor = 'http://127.0.0.1:%s/wd/hub' % port
options = ChromeOptions()
options.add_argument('--start-maximized')
options.add_argument('--no-sandbox')
options.add_argument('--autoplay-policy=no-user-gesture-required')
options.add_argument('--remote-debugging-port=9222')


def test_a():
    driver = webdriver.Remote(
        command_executor=command_executor,
        options=options
    )
    driver.get('https://www.amazon.com/')
    sleep(10)


def test_b():
    driver = webdriver.Remote(
        command_executor=command_executor,
        options=options
    )
    driver.get('https://google.com')
    sleep(10)


def test_c():
    driver = webdriver.Remote(
        command_executor=command_executor,
        options=options
    )
    driver.get('https://facebook.com/')
    sleep(10)

执行命令:

py.test -n 3 tests/tests

环境信息:

  • Python版本:3.11.4
  • pytest-xdist版本:3.3.1
  • Selenium Server启动命令:
java -jar selenium-server-4.10.0.jar standalone

解决方案

1. 移除固定的--remote-debugging-port参数

问题核心是所有测试用例共享了同一个固定调试端口9222,第一个Chrome实例启动后占用该端口,后续测试会复用这个实例而非启动新实例。直接删除该参数即可,Selenium Server会自动为每个会话分配独立的调试端口。

2. 确保每个测试使用独立的ChromeOptions实例

全局options变量可能在并行执行时出现状态共享问题,建议通过函数或fixture为每个测试生成独立的配置实例。

3. 测试结束后主动关闭driver

未关闭driver会导致会话残留,浪费资源且可能影响后续测试,需在测试末尾调用driver.quit(),或用pytest fixture自动管理生命周期。


修改后的代码示例(基础版)

from time import sleep
from selenium import webdriver
from selenium.webdriver import ChromeOptions

port = 4444
command_executor = 'http://127.0.0.1:%s/wd/hub' % port

def get_chrome_options():
    options = ChromeOptions()
    options.add_argument('--start-maximized')
    options.add_argument('--no-sandbox')
    options.add_argument('--autoplay-policy=no-user-gesture-required')
    # 移除固定调试端口参数
    return options

def test_a():
    driver = webdriver.Remote(
        command_executor=command_executor,
        options=get_chrome_options()
    )
    try:
        driver.get('https://www.amazon.com/')
        sleep(10)
    finally:
        driver.quit()

def test_b():
    driver = webdriver.Remote(
        command_executor=command_executor,
        options=get_chrome_options()
    )
    try:
        driver.get('https://google.com')
        sleep(10)
    finally:
        driver.quit()

def test_c():
    driver = webdriver.Remote(
        command_executor=command_executor,
        options=get_chrome_options()
    )
    try:
        driver.get('https://facebook.com/')
        sleep(10)
    finally:
        driver.quit()

更优雅的Fixture版本

import pytest
from time import sleep
from selenium import webdriver
from selenium.webdriver import ChromeOptions

port = 4444
command_executor = 'http://127.0.0.1:%s/wd/hub' % port

@pytest.fixture(scope="function")
def driver():
    options = ChromeOptions()
    options.add_argument('--start-maximized')
    options.add_argument('--no-sandbox')
    options.add_argument('--autoplay-policy=no-user-gesture-required')
    driver_instance = webdriver.Remote(
        command_executor=command_executor,
        options=options
    )
    yield driver_instance
    # 测试结束自动关闭driver
    driver_instance.quit()

def test_a(driver):
    driver.get('https://www.amazon.com/')
    sleep(10)

def test_b(driver):
    driver.get('https://google.com')
    sleep(10)

def test_c(driver):
    driver.get('https://facebook.com/')
    sleep(10)

修改后执行原命令py.test -n 3 tests/tests即可实现每个测试用例启动独立的Chrome实例。

内容的提问来源于stack exchange,提问作者sridhar249

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 12:35:36