如何使用单个全局selenium驱动程序来节省内存

问题描述 投票:0回答:1

TLDR:我创建了多个硒驱动程序来测试不同的功能,并且使用了太多的内存。有没有办法限制selenium的内存使用? (我已经无头跑了)

所以我使用 selenium 和 pytest 在我的网站上运行测试。为了设置运行这些测试的正确环境,我使用多个函数/装置在其中创建另一个驱动程序,并在完成后关闭驱动程序。

但是这种方法对我来说是有问题的,因为它使用了太多内存,并且每次我尝试运行/调试时都会使我的机器崩溃。我的测试使用不同的文件中的几个实用函数,并创建它们自己的驱动程序来完成它们的工作。我想知道的是我是否可以使用单个驱动程序来执行这些实用功能。

这是我尝试运行的测试。

from lib.driver_options import get_driver_options
import lib.resetEnvr as resetEnvr
import lib.sayTRUST_ClientGroup as groupmanager
#... other imports
@pytest.fixture(scope="module")
def load_config():
        file_path = os.path.dirname(__file__)
        config_file_path = os.path.join(os.path.dirname(os.path.dirname(file_path)), 'config', 'website_config.json')
        vz_config_path = os.path.join(os.path.dirname(os.path.dirname(file_path)), 'config',
                                      'cloud_testserver.json')

        with open(config_file_path) as f:
            configurations = json.load(f)
        with open(vz_config_path) as f:
            vz_config = json.load(f)

        default_config = configurations['default_config']
        keyfile = os.path.join(os.path.dirname(os.path.dirname(file_path)), 'config', 'Service_PrivateKey_RSA')

        return {
            'default_config': default_config,
            'vz_config': vz_config,
            'keyfile': keyfile
        }

class Test_NetworkAccess():
    """
    Test cases:
        Changing the network settings and making sure they all work.
    """
    NATBUDDY_PRIVIP = "1.2.3.4"
    NATBUDDY_PUBIP = "1.2.3.4"
    TCPPORT = 8360
    UDPPORT = 8361
    config =None

    @pytest.fixture(scope="function")
    def setup_environment(self, load_config):
        print("setup method")
        options = get_driver_options()
        service = Service()
        driver = webdriver.Chrome(service=service, options=options)
        driver.implicitly_wait(2)
        vars = {}
        # env reseter cleans up the websites state after each testing.
        env_reseter = resetEnvr.dbCleaner()
        
        ifaces = load_config['vz_config']["TemplateVM_info"]["network interfaces"]
        for iface in ifaces:
            for fixed_ip in iface.get("fixed_ips", []):
                ip = fixed_ip.get("ip_address", "")
                if ip.startswith("10.236."):
                    pub_ip = ip
                else:
                    priv_ip = ip
        # try to delete previous settings.
        try:
            groupmanager.delete_testClients()
        except:
            pass
        try:
            groupmanager.delete_testGroup()
        except:
            pass
        yield {
            'driver': driver,
            'env_reseter': env_reseter,
            'pub_ip': pub_ip,
            'priv_ip': priv_ip,
            'vars': vars
        }

        # Teardown after each test function

        driver.close()
        driver.quit()
    @pytest.fixture(scope="module", autouse=True)
    def setup_iface(self):
        print("setup interface")
        print("add_listenPort")

        groupmanager.add_listenPort()
        print("add_private_iface")
        groupmanager.add_private_iface()
        env_reseter = resetEnvr.dbCleaner()
        print("get backup")
        env_reseter.getBackup()
    @pytest.fixture(scope="function")
    def create_test_group(self,request, setup_environment):
        print("create test group")
        params = request.param
        groupmanager.create_testGroup(**params)
        print("create test group yields")
        yield
        # Teardown 
        groupmanager.delete_testGroup()

    @pytest.fixture(scope="function")
    def create_test_client(self, request, create_test_group):
        params = request.param
        print("create test client")
        groupmanager.create_testClient(**params)
        print("create test client yields")
        yield
        # teardown
        groupmanager.delete_testClients()

    

    @pytest.mark.parametrize("create_test_group", [
        {"NATBuddyPub": False, "TCP": True, "UDP": False, "SSH": True},
        {"NATBuddyPub": True, "TCP": True, "UDP": False, "SSH": True},
        # Add other configurations as needed
    ], indirect=True)
    @pytest.mark.parametrize("create_test_client", [
        {},
    ], indirect=True)
    @pytest.mark.usefixtures("setup_environment","create_test_group","create_test_client")
    def test_NATBuddyGroupPubSSH(self,setup_environment,create_test_group,create_test_client, record_xml_attribute ,request):

        # do some testing without using Driber
       print("do some testing")

这里是其他实用程序如何使用 selenium 驱动程序的示例 以及我用于驱动程序的设置。他们都以相同的方式使用驱动程序。


def get_driver_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    options.add_argument("--window-size=1440, 900")
    options.add_argument('--ignore-certificate-errors')
    options.add_argument('--allow-running-insecure-content')
    options.add_argument("--disable-extensions")
    options.add_argument("--proxy-server='direct://'")
    options.add_argument("--proxy-bypass-list=*")
    options.add_argument("--start-maximized")
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument("--FontRenderHinting[none]")
    options.add_argument('--no-sandbox')
    options.add_argument('log-level=3')
    options.add_argument('--ignore-ssl-errors=yes')
    options.add_argument('--allow-insecure-localhost')

    return options

def add_private_iface():

    options = get_driver_options()
    service = Service()
    driver = webdriver.Chrome(service=service, options=options)
    driver.implicitly_wait(15)
    website_url = default_config["website_url"]
    driver.get(website_url)
    # do some stuff
    # add some private interface to website
    driver.find_element(By.LINK_TEXT, "Logout").click()
    driver.close()
    driver.quit()

当我运行这些测试时,我发现 Google chrome 星使用了大量的 CPU,而我的机器死机了。

我之前曾尝试通过将驱动程序作为参数传递来运行这些函数,但它似乎不起作用并给出了一堆奇怪的错误。在尝试使其发挥作用后,我决定这样做,但现在我有疑问。是否有可能为所有这些制作一个单一的硒驱动程序?

或者也许我遗漏了一些东西,也许驱动程序中有一些东西我忘记在函数调用之间杀死。我已经在使用 chrome driver headless,所以我不知道任何其他设置。

我不认为问题出在 pyton 的另一部分,因为我确实观察到当程序运行时,任务管理器中启动了多个 chrome 实例,这就是限制我的 CPU 使用率的原因。

unit-testing selenium-webdriver selenium-chromedriver pytest
1个回答
0
投票

我不是Python专家,但是您所说的问题可以使用单例设计模式来解决。您基本上检查该对象是否为空,万一它为空?你初始化它,当它不是时,你返回之前初始化的实例。

它应该类似于下面的代码片段:

class WebBrowser:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(WebBrowser, cls).__new__(cls)
            options = get_driver_options()
            service = Service()
            driver = webdriver.Chrome(service=service, options=options)
            driver.implicitly_wait(15)
            cls._instance.driver = webdriver.Chrome()
        return cls._instance

    def get_driver(self):
        return self.driver

    def close_driver(self):
        if self.driver:
            self.driver.quit()
            WebBrowser._instance = None

然后可以在测试中使用它,如下所示:

browser = WebBrowser().get_driver()
browser.get("https://duckduckgo.com")

注意:如果您希望网络驱动程序的类型也是动态的,我建议您也阅读工厂设计模式。

© www.soinside.com 2019 - 2024. All rights reserved.