如果使用python,则需要减少多个else
我正在尝试使用SeleniumWebDriver和python自动化基本html网站的回归测试。我编写了一个函数,该函数将从excel中获取输入,以确定网页上元素的定位器类型,如下所示:如果使用python,则需要减少多个else,python,python-3.x,selenium-webdriver,Python,Python 3.x,Selenium Webdriver,我正在尝试使用SeleniumWebDriver和python自动化基本html网站的回归测试。我编写了一个函数,该函数将从excel中获取输入,以确定网页上元素的定位器类型,如下所示: if locator_type == "ID": web_element = self.__driver.find_element_by_id(element) elif locator_type == "NAME":
if locator_type == "ID":
web_element = self.__driver.find_element_by_id(element)
elif locator_type == "NAME":
web_element = self.__driver.find_element_by_name(element)
elif locator_type == "XPATH":
web_element = self.__driver.find_element_by_xpath(element)
elif locator_type == "TAG_NAME":
web_element = self.__driver.find_element_by_tag_name(element)
elif locator_type == "LINK_TEXT":
web_element = self.__driver.find_element_by_link_text(element)
elif locator_type == "CLASS_NAME":
web_element = self.__driver.find_element_by_class_name(element)
elif locator_type == "PARTIAL_LINK_TEXT":
web_element = self.__driver.find_element_by_partial_link_text(element)
这样,我们就可以指定定位器类型并给出实际的定位器(“元素”),以便selenium可以尝试在web页面上查找web元素。有没有办法减少elif语句或其他更好的方法来编写本部分
我在上面的链接中尝试了这个方法,但是没有帮助。请帮我解决这个问题
编辑
我试着创造一个这样的口述
locator_dict = {
'ID' : driver.find_element_by_id(element),
'NAME' : driver.find_element_by_name(element)}
然后我收到一个错误,说元素未定义您可以从
定位器类型
构造要调用的函数名,然后调用它:
locator_type_lower = locator_type.lower()
find_function_name = 'find_element_by_{}'.format(locator_type_lower)
driver_function_to_call = getattr(self.__driver, find_function_name)
web_element = driver_function_to_call(element)
您可能应该将其包装在一些错误检查中—检查函数是否存在,检查它是否可调用,等等
它的作用是:
将定位器类型转换为小写,然后在self.\uu驱动程序中构建现有函数的函数名,然后使用元素调用它
这种方法的优点是,您不必将字符串映射到函数-如果self.\uu驱动程序
有一个名为find\u element\u by\u foo\u bar\u length
的函数,那么您只需将foo\u bar\u length
添加到excel电子表格中,它就会被调用,无需更新映射命令
编辑:更新评论
要将定位器类型字符串转换为By
类的属性,请执行以下操作:
locator_type = 'ID'
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((getattr(By, locator_type), element)))
不同子句主体之间的唯一区别是实际调用的方法。您可以将其分解为一个
命令
d = {
"ID": self.__driver.find_element_by_id,
"NAME": self.__driver.find_element_by_name,
# etc
}
if locator_type in d:
web_element = d[locator_type](element)
else:
# do something if you haven't defined a method for locator_type
您也可以使用methodcaller
,尽管第一次尝试使d
依赖于元素
:
from operator import methodcaller
methods = [
("ID", "find_element_by_id"),
("NAME", "find_element_by_name"),
# etc
]
d = { tag: methodcaller(method, element) for tag, method in methods }
if locator_type in d:
web_element = d[locator_type](self.__driver)
要完全独立于驱动器或元件,请使用
d = dict(methods)
if locator_type in d:
web_element = methodcaller(d[locator_type], element)(self.__driver)
你能详细说明为什么你链接的答案对你没有帮助吗?dict似乎可以大大减轻示例代码中的多个
if
和elif
块。你是不是很难弄清楚如何散列函数调用?也就是说,如何在散列中存储函数。@MikeHolt我不明白散列函数调用有什么帮助?请给我一些见解。对不起,我的措辞有点马虎。我指的是将函数作为值存储在散列中(在Python中称为dict),正如chepner的回答所示。非常感谢您澄清这一点,我会尝试一下并向您更新。这很有效,但有一个小问题。。在调用字典之前需要实例化驱动程序对象?如图所示,是的。我将使用methodcaller
添加一个解决方案,我省略了它,因为它看起来有点复杂,但使d
独立于驱动程序。切普纳,你能再次提供帮助吗?如何在selenium中为显式等待函数生成方法调用方。示例:“WebDriverWait(driver,10).until(EC.presence\u of_element\u located((By.ID,“myDynamicElement”)))””嘿,Danielle,我们有没有办法为下面的语句实现这一点?“WebDriverWait(driver,10)。直到(EC.presence\u元素位于((By.ID,“myDynamicElement”))))””。我尝试了以下方法:driver.get('https://www.google.com/“)locator_type='NAME'element='q'exp_wait_str=“WebDriverWait({},10)。直到(EC.presence_of_element_located((By.{},{}))”。format(driver,locator_type,element)fun=getattr(driver,exp_wait_str)web_element=fun(locator_type,element)
我试图理解这个概念,但无法使用您为上述陈述建议的方法。请调查一下,你好!您试图做的是动态地从By类中提取locator_类型。我将更新上面的答案,告诉你如何做到这一点。非常感谢Danielle,它起到了很好的作用,你帮助删除了30多行重复代码。