与findElement()一起使用的最有效的选择器是什么?
使用Selenium Web测试时,有几种方法可以识别WebElements。
根据我的经验,我使用了以下选择器:
- 类名 –
By.className()
- CSS选择器 –
By.cssSelector()
- ID –
By.id()
- 链接文本 –
By.linkText()
- 名称 –
By.name()
- 标签名称 –
By.tagName()
- XPath –
By.xpath()
显然,当只有一个选项可用于定位元素时,我们必须使用那个,但是当可以使用多个方法时(例如:下面的div),应该如何确定使用哪种方法? 选择器是否比其他选择器效率更高? 有些更耐用吗?
Here's a div
仅适用于s&gs ……
我计时每个标识符方法在五个单独的时间内找到div并平均找到元素所花费的时间。
WebDriver driver = new FirefoxDriver(); driver.get("file:///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();
它们按平均运行时间排序。
- CssSelector :(796ms + 430ms + 258ms + 408ms + 694ms)/ 5 = ~517.2ms
- ClassName 🙁 670ms + 453ms + 812ms + 415ms + 474ms)/ 5 = ~564.8ms
- 名称 :(342ms + 901ms + 542ms + 847ms + 393ms)/ 5 = ~605ms
- ID :(888ms + 700ms + 431ms + 550ms + 501ms)/ 5 = ~614ms
- Xpath :(835ms + 770ms + 415ms + 491ms + 852ms)/ 5 = ~672.6ms
- TagName :(998ms + 832ms + 1278ms + 227ms + 648ms)/ 5 = ~796.6ms
在阅读@JeffC的回答后,我决定将By.cssSelector()
与classname,tagname和id作为搜索词进行比较。 再次,结果如下……
WebDriver driver = new FirefoxDriver(); driver.get("file:///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 = ~199ms -
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选择器来做你能做的一切!
根据我的经验,我按以下顺序使用这些定位器:
- ID
- LINKTEXT / partialLinkText
- CSS选择器
- XPath的
其他:类名,标签名,名称等都可以使用CSS选择器找到。 我很少需要一个类名,所以我更喜欢CSS选择器,这样我就可以使用多个类,但也指定一个标签名称,使其更具体,更不容易破坏。 很少使用标记名称…除非我们讨论的是TABLE或TR或TD标记,否则这些标记都可以使用CSS选择器完成。 我通常发现带有name
标签也有id
所以我更喜欢id
。
我最近发现,正如你在答案中所做的那样,CSS选择器是最快的。 这是有道理的,因为Selenium正在使用浏览器进行搜索,而CSS选择器非常常见,以至于不同的浏览器都为其使用提供了优化的性能。
linkText / partialLinkText非常专业,所以我真的不算数。 我尽可能地使用它们,这是有道理的。 我曾经考虑过只使用By.cssSelector("#someId")
但我认为它并没有真正产生太大的影响,使用Id时By.id()
会更加明显。
我很少使用XPath,只有当我无法用其他定位器完成它时,例如在标签的文本或一些奇怪的子/后代的事情中我无法使用CSS选择器。 我发现(并阅读)XPath支持因浏览器而异,并且速度较慢所以除非绝对必要,否则我会避免它……我发现你可以找到99%的#1-3元素。
ids应该是最耐用的。 LinkText和partialLinkText可能相当耐用,具体取决于页面。 应用的类和用于CSS选择器的HTML结构可能最有可能随页面更新而更改。 这实际上取决于更新的大小,以确定页面的部分部分是否已更改。 CSS选择器和XPath都会(通常)受到这些类型的更改的影响。
最后……只要您没有抓取数百个元素的页面,一个页面转换可能比定位器方法之间几百毫秒的差异更重要。
我优先选择这样的选择器:
- ID –
By.id()
- 名称 –
By.name()
- CSS选择器 –
By.cssSelector()
- XPath –
By.xpath()
- 标签名称 –
By.tagName()
- 链接文本 –
By.linkText()
但是,uniq ID和Names并不总是存在。 您还可以使用CSS选择器按ID #element_id
或Name [name=element_name]
或ClassName .element_class
,因此最好使用CSS选择器而不是ID
, Name
和ClassName
。 Css比xPath快,所以最好尽可能使用它。 xPath适用于CSS选择器无法找到的困难元素定位器。 我也不会使用标签名称和链接文本,因为你可以用xPath编写相同的内容(对于链接文本//a[text()='link_text']
,标签名称//div
)或CSS选择器(用于标签名称div
)。
定位器应该具有描述性,独特性,并且不太可能发生变化 。 所以我的优先顺序如下:
- ID – 您将获得所需的确切元素,它可以是描述性的,不会被错误地更改。
- 类 – 非常具有描述性,在父元素的上下文中可能是唯一的。
- CSS – 比XPath更好的性能 – 请参阅Dave Haeffner的伟大基准 。
- XPath – 具有CSS不喜欢Axis的function,例如
::parent
和像contains()
这样的函数。
我会避免使用LinkText
和TagName
因为它们会因非常通用的过滤而导致意外故障。
关于CSS和XPath的注意事项 :使用//div/li[1]/*/span[2]
或div > li:nth-child(1)
也应该避免,因为它们取决于渲染并且倾向于变化。