查找元素并不总是成功。这能改进吗?



我有一个特定的脚本,它引用了我测试的UI中的某些元素。 有些元素通过它们的 ID 定位,有些元素通过它们的 Xpath 定位。此脚本在特定场景后从我的 UI 收集一些信息。我反复调整此脚本以找到特定结果。

大多数情况下,所有元素都已找到。碰巧在大约 100 个(有时在几十个周期之后(循环后,脚本停止,大多数情况下它与未找到的元素有关。 我知道这种自动化故障很常见,我还假设有时它可能与与我的 UI(甚至与 UI 管理的设备(相关的某个问题有关。

是否有可能/建议以对某些情况更宽容的方式设计我的自动化(顺便说一下,我确实使用了内置的隐式等待(?

是否建议在这些测试之王中创建重试机制?

这是脚本:

from selenium import webdriver
from datetime import datetime
import time

def main():
i = 0
while True:
i = i +1
execute_code(i)
if i == 500:
break
def Cold_Restart(browser):
browser.switch_to.default_content()
browser.switch_to.frame('box_menu')
browser.switch_to.frame('box_menu')
SysBtn = browser.find_element_by_id('System')
SysBtn.click()
browser.switch_to.default_content()
browser.switch_to.frame('main_menu')
Mainten_Btn = browser.find_element_by_id('Maintenance')
Mainten_Btn.click()
browser.switch_to.default_content()
browser.switch_to.frame('main_body')
Mntn_Rst_Tab = browser.find_element_by_id('tab_restart')
Mntn_Rst_Tab.click()
browser.switch_to.frame('maint_sys')
Cold_Rst_Btn = browser.find_element_by_id('cold_restart')
Cold_Rst_Btn.click()
#In order to confirm the Alert Message I first need to switch to the alert pop-up message and then accept it
alertDialog = browser.switch_to_alert()
alertDialog.accept()
time.sleep(205)
return

def Port_Admin_Down(browser):
browser.switch_to.default_content()
browser.switch_to.frame('box_menu')
browser.switch_to.frame('box_menu')
Port_19 = browser.find_element_by_id('Port-19')
Port_19.click()

browser.switch_to.default_content()
# Show the Port Configuration TAB
browser.switch_to.frame('main_body')
CFP2_Info = browser.find_element_by_id('tab_general')
CFP2_Info.click()
browser.switch_to.frame('config_port') # Move to the inner frame that holds the configuration fields and buttons
Admin_Down_Btn = browser.find_element_by_id('red_button')
Admin_Down_Btn.click()
#In order to confirm the Alert Message I first need to switch to the alert pop-up message and then accept it
alertDialog = browser.switch_to_alert()
alertDialog.accept()
time.sleep(5)
return

def Port_Admin_Up(browser):
browser.switch_to.default_content()
browser.switch_to.default_content()
browser.switch_to.frame('box_menu')
browser.switch_to.frame('box_menu')
Port_19 = browser.find_element_by_id('Port-19')
Port_19.click()
browser.switch_to.default_content()
# Show the Port Configuration TAB
browser.switch_to.frame('main_body')
CFP2_Info = browser.find_element_by_id('tab_general')
CFP2_Info.click()
browser.switch_to.frame('config_port') # Move to the inner frame that holds the configuration fields and buttons
Admin_Down_Btn = browser.find_element_by_id('green_button')
Admin_Down_Btn.click()
#In order to confirm the Alert Message I first need to switch to the alert pop-up message and then accept it
alertDialog = browser.switch_to_alert()
alertDialog.accept()    
time.sleep(5)
return
def Gui_Login(browser, URL):
browser.get(URL)
#    browser.implicitly_wait(20) # Implicit wait

browser.maximize_window()
# Find the User Name text box and fill the User name
user_name_box = browser.find_element_by_id('u_name_box')
user_name_box.click()
user_name_box.send_keys('admin')
# Find the Password text box and fill the Password
user_pass_box = browser.find_element_by_id('u_pass_box')
user_pass_box.click()
user_pass_box.send_keys('admin')
#webdriver.ActionChains(driver).send_keys(Keys.ESCAPE).perform()
login_button = browser.find_element_by_id('login_but')
login_button.click()
return
def Gui_Logout(browser):
browser.switch_to.default_content() # Get back to the default starting point

# In order to click the Logout button I needed to pass through two frames
browser.switch_to.frame('box_menu')
browser.switch_to.frame('box_menu')
logout_btn = browser.find_element_by_id('Logout')
logout_btn.click()
return
def Sample_Uplink(browser):
browser.switch_to.default_content()
# Go to the Configuration Pane (main_menu)
browser.switch_to.frame('main_menu')
Configuration_Btn = browser.find_element_by_id('Configuration')
Configuration_Btn.click()
browser.switch_to.default_content()
# Go to the Uplink 1 CFP2 information and take the Rx Pwr
browser.switch_to.frame('box_menu')
browser.switch_to.frame('box_menu')
Port_19 = browser.find_element_by_id('Port-19')
Port_19.click()
browser.switch_to.default_content()
# Show the Optic Module information TAB
browser.switch_to.frame('main_body')
CFP2_Info = browser.find_element_by_id('tab_XFP')
CFP2_Info.click()
# Collect the Rx Pwr from the CFP2 Info screen
browser.switch_to.frame('config_port') # Move to the inner frame that holds all the tables
#browser.find_element_by_class_name('table_round_corner')
Rx_Pwr = browser.find_element_by_xpath('html/body/form/div[1]/div/table/tbody/tr[2]/td[2]') # Take the Rx Pwr according to its Xpath
# print (Rx_Pwr.text) # print the Rx Pwr result to screen
RcvPwr = Rx_Pwr.text
# Collect the OSNR measurement from the CFP2 Info screen
OSNR = browser.find_element_by_xpath('html/body/form/div[1]/div/table/tbody/tr[4]/td[2]')
OSNR_Lvl = OSNR.text

#    time.sleep(5)
return (RcvPwr, OSNR_Lvl)

def Save_2_File(Rx_Pwr, OSNR_Lvl, i):
file = open("test_results.txt", "a")
file.write("%i. " %i)
file.write(datetime.now().strftime('%H:%M:%S %d-%m-%Y    ')) # Print Time & Date to the text file 
file.write(Rx_Pwr) # Print the Rx_Pwr to the text file
file.write('%10s' %(OSNR_Lvl)) # Format the placement of the OSNR value
file.write('n') # Make sure that the next iteration will write the results in the next line
file.close() # Closing the file
return

def execute_code(i):
profile = webdriver.FirefoxProfile()
profile.accept_untrusted_certs = True
browser = webdriver.Firefox(firefox_profile = profile)
browser.implicitly_wait(20) # Implicit wait

URL1 = 'http://10.0.1.131' #  First device that will be Cold Restarted
Gui_Login(browser, URL1)
Cold_Restart(browser)
(RcvPwr, OSNR_Lvl) = Sample_Uplink(browser)
Save_2_File(RcvPwr, OSNR_Lvl, i)
URL2 = 'http://10.0.1.134'
Gui_Login(browser, URL2)
Cold_Restart(browser)
(RcvPwr, OSNR_Lvl) = Sample_Uplink(browser)
Save_2_File(RcvPwr, OSNR_Lvl, i)

browser.get(URL1)
Port_Admin_Down(browser)
Port_Admin_Up(browser)
time.sleep(5)
browser.get(URL2)   
#Get Rx Pwr and OSNR and save in file
(RcvPwr, OSNR_Lvl) = Sample_Uplink(browser)
Save_2_File(RcvPwr, OSNR_Lvl, i)

Port_Admin_Down(browser)
Port_Admin_Up(browser)
time.sleep(5)
browser.get(URL1)   
#Get Rx Pwr and OSNR and save in file
(RcvPwr, OSNR_Lvl) = Sample_Uplink(browser)
Save_2_File(RcvPwr, OSNR_Lvl, i)

browser.quit()

if __name__ == '__main__':
main()

我会wait预期的元素,如果失败,我会exceptNoSuchElementException

try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "Maintenance"))
)
except NoSuchElementException:
# Handle your error case here
else:
element.click()

此时,您可以优雅地停止,重试最后一次调用,只需跳过此测试,等等......


检查蟒蛇硒等待文档


编辑以征求意见

我不是这个的忠实粉丝,但是如果添加一些行困扰您,您可以随时为此制作一种包装器:

def wait_for_func(driver, element_tuple, func_success, func_failed, time=10):
try:
element = WebDriverWait(driver, time).until(
EC.presence_of_element_located(element_tuple)
)
except NoSuchElementException:
return None, func_failed(element)
else:
return element, func_success(element)
def do_click(element):
return element.click()
def do_print():
return 'Something gone wrong'
element, result = wait_for_func(driver, (By.ID, 'Maintenance'), func_success=do_click, func_failed=do_print)

这将避免重复尝试/除了任何地方,但你肯定知道Python的禅:

显式总比隐式好。 简单总比复杂好。 复杂总比复杂好。

无论如何,如果你做这样的事情,你可能会注意到定义一个函数只是为了单击一个元素并不是那么好,所以lambda可以帮助你:

wait_for_func(driver, (By.ID, 'Maintenance'), lambda el: el.click(), do_print)

我发现lambda不是那么漂亮,但如你所愿。

如果你想避免在某些循环中出错。 尝试/捕获会有所帮助。

首先:将一些代码从 execute_code(( 移动到 main,然后尝试/捕获 execute_code((。

def main():
i = 0
while True:
i = i +1
profile = webdriver.FirefoxProfile()
profile.accept_untrusted_certs = True
browser = webdriver.Firefox(firefox_profile = profile)
browser.implicitly_wait(20) # Implicit wait
try:
execute_code(i, browser)
browser.quit()
if i == 500:
break
except:
browser.quit()

第二:修改execute_code((。将浏览器添加为参数。删除代码以初始化/退出网络驱动程序。

def execute_code(i, browser):
URL1 = 'http://10.0.1.131' #  First device that will be Cold Restarted
Gui_Login(browser, URL1)
Cold_Restart(browser)
(RcvPwr, OSNR_Lvl) = Sample_Uplink(browser)
Save_2_File(RcvPwr, OSNR_Lvl, i)
URL2 = 'http://10.0.1.134'
Gui_Login(browser, URL2)
Cold_Restart(browser)
(RcvPwr, OSNR_Lvl) = Sample_Uplink(browser)
Save_2_File(RcvPwr, OSNR_Lvl, i)

browser.get(URL1)
Port_Admin_Down(browser)
Port_Admin_Up(browser)
time.sleep(5)
browser.get(URL2)   
#Get Rx Pwr and OSNR and save in file
(RcvPwr, OSNR_Lvl) = Sample_Uplink(browser)
Save_2_File(RcvPwr, OSNR_Lvl, i)

Port_Admin_Down(browser)
Port_Admin_Up(browser)
time.sleep(5)
browser.get(URL1)   
#Get Rx Pwr and OSNR and save in file
(RcvPwr, OSNR_Lvl) = Sample_Uplink(browser)
Save_2_File(RcvPwr, OSNR_Lvl, i)

相关内容

最新更新