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 使用率的原因。
我不是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")
注意:如果您希望网络驱动程序的类型也是动态的,我建议您也阅读工厂设计模式。