使用Selenium Web测试时,有几种方法可以识别WebElements。
根据我的经验,我使用了以下选择器:
By.className()
By.cssSelector()
By.id()
By.linkText()
By.name()
By.tagName()
By.xpath()
显然,当只有一个选项可用于定位元素时,我们必须使用那个,但是当可以使用多个方法时(例如:下面的div),应该如何确定使用哪种方法?是否存在效率的选择器?是否有一些更持久?
<div class="class" id="id" name="name">Here's a div</div>
答案 0 :(得分:12)
仅适用于s&amp; gs ......
我为每个标识符方法计时,在五个不同的时间内找到div并平均找到该元素所花费的时间。
WebDriver driver = new FirefoxDriver();
driver.get("file://<Path>/div.html");
long starttime = System.currentTimeMillis();
//driver.findElement(By.className("class"));
//driver.findElement(By.cssSelector("html body div"));
//driver.findElement(By.id("id"));
//driver.findElement(By.name("name"));
//driver.findElement(By.tagName("div"));
//driver.findElement(By.xpath("/html/body/div"));
long stoptime = System.currentTimeMillis();
System.out.println(stoptime-starttime + " milliseconds");
driver.quit();
它们按平均运行时间排序。
在阅读@JeffC的答案后,我决定将By.cssSelector()
与classname,tagname和id作为搜索词进行比较。再次,结果低于......
WebDriver driver = new FirefoxDriver();
driver.get("file://<Path>/div.html");
long starttime = System.currentTimeMillis();
//driver.findElement(By.cssSelector(".class"));
//driver.findElement(By.className("class"));
//driver.findElement(By.cssSelector("#id"));
//driver.findElement(By.id("id"));
//driver.findElement(By.cssSelector("div"));
//driver.findElement(By.tagName("div"));
long stoptime = System.currentTimeMillis();
System.out.println(stoptime-starttime + " milliseconds");
driver.quit();
By.cssSelector(".class")
:( 327ms + 165ms + 166ms + 282ms + 55ms)/ 5 = ~1ms By.className("class")
:( 338ms + 801ms + 529ms + 804ms + 281ms)/ 5 = ~550ms By.cssSelector("#id")
:( 58ms + 818ms + 261ms + 51ms + 72ms)/ 5 = ~252ms By.id("id")
- (820ms + 543ms + 112ms + 434ms + 738ms)/ 5 = ~529ms By.cssSelector("div")
:( 594ms + 845ms + 455ms + 369ms + 173ms)/ 5 = ~487ms By.tagName("div")
:( 825ms + 843ms + 715ms + 629ms + 1008ms)/ 5 = ~804ms 从这一点来看,似乎你应该使用css选择器来做你能做的一切!
答案 1 :(得分:5)
根据我的经验,我按此顺序使用这些定位器:
其他:可以使用CSS选择器找到类名,标签名,名称等。我很少需要一个类名,所以我更喜欢CSS选择器,这样我可以使用多个类,但也指定一个标签名称,使其更具体,更不容易中断。很少使用标记名称...除非我们讨论的是TABLE或TR或TD标记,否则这些标记都可以用CSS选择器完成。我通常会发现name
的代码也有id
,所以我更喜欢id
。
我最近发现,正如你在答案中所做的那样,CSS选择器是最快的。这是有道理的,因为Selenium正在使用浏览器进行搜索,而CSS选择器非常常见,以至于不同的浏览器都为其使用提供了优化的性能。
linkText / partialLinkText是非常专业的,所以我并不真正算它们。我尽可能地使用它们,这是有道理的。我曾考虑过只使用By.cssSelector("#someId")
,但我不认为它确实会产生太大的影响,By.id()
在使用Id时会更加明显。
我很少使用XPath,只有当我无法使用其他定位器完成它时,例如对于来自标签的文本或一些奇怪的子/后代的事情我不能用CSS选择器做。我发现(并阅读)XPath支持因浏览器而异,并且速度较慢所以除非绝对必要,否则我会避免使用它......我发现你可以找到99%的#1-3元素。
ids应该是最耐用的。 LinkText和partialLinkText可能相当耐用,具体取决于页面。应用的类和用于CSS选择器的HTML结构可能最有可能随页面更新而更改。它实际上取决于更新的大小,以确定页面的部分部分是否已更改。 CSS选择器和XPath都会(通常)受到这些变化的影响。
最后......只要您没有抓取数百个元素的页面,一个页面转换可能比定位器方法之间几百毫秒的差异更重要。
答案 2 :(得分:2)
我会优先选择这样的选择器:
By.id()
By.name()
By.cssSelector()
By.xpath()
By.tagName()
By.linkText()
但是,uniq ID和Names并不总是存在。您还可以使用CSS选择器按ID #element_id
或按名称[name=element_name]
或按ClassName .element_class
进行查找,因此最好使用CSS选择器ID
,{{ 1}}和Name
。 Css比xPath快,所以最好尽可能使用它。 xPath适用于CSS选择器无法找到的困难元素定位器。我也不会使用标记名称和链接文本,因为您可以使用xPath(对于链接文本ClassName
,标记名称//a[text()='link_text']
)或CSS选择器(对于标记名//div
)编写相同的内容
答案 3 :(得分:1)
定位器应具有描述性,唯一且不太可能更改。所以我的优先事项如下:
::parent
以及contains()
。我会避免使用LinkText
和TagName
,因为它们会因非常通用的过滤而导致意外失败。
关于CSS和XPath的注意事项:使用//div/li[1]/*/span[2]
或div > li:nth-child(1)
之类的内容也应该避免,因为它们取决于渲染和容易发生变化。