cssSelector와 Xpath의 차이점은 무엇이며 크로스 브라우저 테스트의 성능면에서 어느 것이 더 낫습니까?


89

저는 다국어 웹 애플리케이션에서 Selenium WebDriver 2.25.0으로 작업하고 있으며 주로 페이지 콘텐츠를 테스트합니다 (아랍어, 영어, 러시아어 등과 같은 다른 언어의 경우).

성능에 따라 더 나은 내 응용 프로그램의 경우 모든 브라우저 (예 : IE 7,8,9, FF, Chrome 등)를 지원해야합니다.

귀하의 소중한 제안에 미리 감사드립니다.

답변:


109

CSS 선택기는 Xpath보다 성능이 훨씬 뛰어나며 Selenium 커뮤니티에 잘 문서화되어 있습니다. 몇 가지 이유가 있습니다.

  • Xpath 엔진은 브라우저마다 다르므로 일관성이 없습니다.
  • IE에는 기본 xpath 엔진이 없으므로 셀레늄은 API 호환성을 위해 자체 xpath 엔진을 삽입합니다. 따라서 WebDriver가 본질적으로 홍보하는 기본 브라우저 기능을 사용하는 이점을 잃게됩니다.
  • Xpath는 복잡 해지는 경향이 있으므로 내 의견으로는 읽기 어렵습니다.

그러나 xpath를 사용해야하는 상황이 있습니다. 예를 들어 상위 요소를 검색하거나 해당 텍스트로 요소를 검색합니다 (나중에 권장하지 않음).

여기 에서 Simon의 블로그를 읽을 수 있습니다 . 그는 또한 Xpath보다 CSS를 권장합니다.

콘텐츠를 테스트하는 경우 요소의 콘텐츠에 종속 된 선택기를 사용하지 마십시오. 이는 모든 로케일에 대한 유지 관리 악몽이 될 것입니다. 개발자와 대화를 시도하고 사전 또는 리소스 번들 등과 같이 애플리케이션의 텍스트를 외부화하는 데 사용한 기술을 사용하십시오. 여기 에 자세히 설명하는 블로그 가 있습니다.

편집 1

@parishodak 덕분에 CSS 성능이 더 우수하다는 것을 증명하는 숫자를 제공하는 링크 가 있습니다.


7
CSS 선택기는 텍스트를 허용하지 않습니다. 'contains'는 CSS에서 더 이상 사용되지 않습니다. 위에서 말했듯이 콘텐츠와 독립적 인 선택기를 사용합니다. 콘텐츠는 외부에있을 수 있습니다. 개발자와 대화 할 수 있습니다. 그들은 텍스트를 외부화 했음에 틀림 없다. 대부분의 경우 로케일 당 사전이 있습니다. 따라서 사전의 키는 동일하지만 값은 로케일에 따라 변경됩니다. 이러한 파일을 사용하여 콘텐츠의 유효성을 검사 할 수 있습니다. JDK의 nativ2ascii 도구를 사용하여 원시 문자를 ASCII 문자로 변환해야합니다. 이것에 대한 블로그를 작성해야합니다. 이 기술을 사용하여 많은 로케일을 테스트했습니다.
nilesh

1
@Chetan चेतन 답변에 블로그 링크를 추가했습니다. 시간이 좀 걸 렸어요. 도움이 되었기를 바랍니다.
nilesh

8
@Nilesh : 귀하의 답변에 동의하지 않습니다. 1.) CSS 엔진도 브라우저마다 다릅니다. 이것은 논쟁이 아닙니다. 3.) 경험이 있으면 XPath는 이해하기 매우 쉽고 CSS보다 더 많은 기능을 제공합니다. 매우 중첩 된 요소를 검색하는 경우 둘 다 복잡합니다 : XPath와 CSS. 내 경험상이 질문에 대한 일반적인 대답은 틀릴 것입니다. 결정 CSS / XPATH는 개별적으로 이루어져야합니다. 원래 질문은 성능에 관한 것이 었습니다. 귀하의 대답은 주로 가정과 개인적인 의견으로 구성됩니다. 실제 증명은 성능을 측정하고 여기에 결과를 게시하는 것입니다.
Elmue

2
첫 번째 문장과 모순되는 아주 좋은 기사 : "CSS 선택기가 Xpath보다 훨씬 더 잘 수행됩니다". 그렇게 간단하지 않고 그 반대 일 수도 있습니다. "IE에는 기본 xpath 엔진이 없으므로 셀레늄은 API 호환성을 위해 자체 xpath 엔진을 주입합니다." 여기서 Selenium은 설계 오류로 어려움을 겪습니다. 자바 스크립트 대신 C ++에서 XPath 엔진을 구현하는 것이 분명 더 좋았을 것입니다. 그러나 IE는 죽었고 이제 Edge가 왔습니다. 모든 성능 질문 뒤에는 CSS가 요소의 텍스트 검색과 같은 매우 중요한 기능이 없다는 것을 잊지 말아야합니다.
Elmue

2
elementalselenium.com/tips/32-xpath-vs-css 는 css3가 더 이상 크게 빠르지 않다는 벤치 마크를 제공합니다.
mc0e

46

나는 XPath가 장기적으로 CSS 보다 바람직 하다는 SO 셀레늄 태그 의견에 대해 인기가 없을 것 입니다.

이 긴 게시물에는 두 섹션이 있습니다. 먼저 두 섹션의 성능 차이가 0.1-0.3 밀리 초 (예, 100 마이크로 초) 라는 냅킨 증명을 넣은 다음 그 이유를 공유하겠습니다. XPath가 더 강력합니다.


성능 차이

먼저 "방에있는 코끼리"에 대해 살펴 보겠습니다. xpath가 css보다 느립니다.

현재 CPU 성능 (읽기 : 2013 년 이후로 생산 된 모든 x86) , 심지어 browserstack / saucelabs / aws VM 및 브라우저의 개발 (읽기 : 지난 5 년 동안 인기있는 모든 것) 에서는 거의 해당되지 않습니다. 브라우저의 엔진이 개발되었고 xpath의 지원은 균일하며 IE는 그림에서 벗어났습니다 (대부분의 사람들에게 희망을줍니다) . 다른 답변에 대한이 비교는 곳곳에서 인용되고 있지만, IE8에 대해 자동화를 실행하고 있거나 관심을 갖는 것은 매우 맥락 적입니다.

차이가있는 경우 밀리 초 미만 입니다.

그러나 대부분의 상위 레벨 프레임 워크는 어쨌든 원시 셀레늄 호출 (래퍼, 핸들러, 상태 저장 등)에 대해 최소 1ms의 오버 헤드를 추가합니다. 제가 선택한 무기 인 RobotFramework는 최소 2ms를 추가합니다.이 무기는 제공하는 것을 희생하는 것보다 더 기쁩니다. AWS us-east-1에서 BrowserStack의 허브로의 네트워크 왕복은 일반적으로 11 밀리 초 입니다.

따라서 원격 브라우저에서 xpath와 css 사이에 차이가 있으면 다른 모든 것에 의해 가려집니다.


측정

공개적인 비교는 그리 많지 않습니다 (인용 된 것만 본 적이 있습니다) . 여기에 대략적인 단일 사례, 더미 및 간단한 사례가 있습니다.
두 가지 전략으로 요소를 X 번 찾고 그에 대한 평균 시간을 비교합니다.

대상 – BrowserStack의 랜딩 페이지 및 "가입"버튼 이 게시물을 작성하는 동안의 html 스크린 샷 :

여기에 이미지 설명 입력

다음은 테스트 코드 (python)입니다.

from selenium import webdriver
import timeit


if __name__ == '__main__':

    xpath_locator = '//div[@class="button-section col-xs-12 row"]'
    css_locator = 'div.button-section.col-xs-12.row'

    repetitions = 1000

    driver = webdriver.Chrome()
    driver.get('https://www.browserstack.com/')

    css_time = timeit.timeit("driver.find_element_by_css_selector(css_locator)", 
                             number=repetitions, globals=globals())
    xpath_time = timeit.timeit('driver.find_element_by_xpath(xpath_locator)', 
                             number=repetitions, globals=globals())

    driver.quit()

    print("css total time {} repeats: {:.2f}s, per find: {:.2f}ms".
          format(repetitions, css_time, (css_time/repetitions)*1000))
    print("xpath total time for {} repeats: {:.2f}s, per find: {:.2f}ms".
          format(repetitions, xpath_time, (xpath_time/repetitions)*1000))

Python에 익숙하지 않은 사용자를 위해 페이지를 열고 요소를 찾습니다. 먼저 css 로케이터를 사용한 다음 xpath를 사용합니다. 찾기 작업이 1,000 회 반복됩니다. 출력은 1,000 회 반복에 대한 총 시간 (초)과 하나의 발견에 대한 평균 시간 (밀리 초)입니다.

로케이터는 다음과 같습니다.

  • for xpath – "DOM 어딘가에이 정확한 클래스 값을 갖는 div 요소";
  • CSS도 비슷합니다. "DOM 어딘가에이 클래스가있는 div 요소"입니다.

과도하게 조정되지 않도록 의도적으로 선택되었습니다. 또한 클래스 선택기는 CSS에 대해 "id 다음으로 두 번째로 빠른"것으로 인용됩니다.

환경 – Chrome v66.0.3359.139, chromedriver v2.38, cpu : 일반적으로 1.5GHz에서 실행되는 ULV Core M-5Y10 (예, '워드 프로세싱', 일반 i7 야수도 아님) .

출력은 다음과 같습니다.

css total time 1000 repeats: 8.84s, per find: 8.84ms

xpath total time for 1000 repeats: 8.52s, per find: 8.52ms

분명히 검색 당 타이밍은 매우 가깝습니다. 차이는 0.32 밀리 초 입니다. "xpath가 더 빠름"으로 점프하지 마십시오. 때로는 그렇고, 때로는 CSS이기도합니다.


조금 더 복잡한 다른 로케이터 세트를 사용해 봅시다. 하위 문자열을 가진 속성 (적어도 저에게는 일반적인 접근 방식, 일부가 기능적 의미를 가질 때 요소의 클래스를 따라갑니다) :

xpath_locator = '//div[contains(@class, "button-section")]'
css_locator = 'div[class~=button-section]'

두 로케이터는 다시 의미 상 동일합니다. "클래스 속성에이 하위 문자열이있는 div 요소 찾기"입니다.
결과는 다음과 같습니다.

css total time 1000 repeats: 8.60s, per find: 8.60ms

xpath total time for 1000 repeats: 8.75s, per find: 8.75ms

0.15ms차이 .


실습으로- 링크 된 블로그 의 댓글 / 기타 답변에서 수행 한 것과 동일한 테스트 - 테스트 페이지 는 공개이며 테스트 코드도 마찬가지입니다 .

그들은 코드에서 몇 가지 작업을 수행하고 있습니다. 열을 클릭하여 정렬 한 다음 값을 가져오고 UI 정렬이 올바른지 확인합니다.
잘라 버릴 게요-그냥 로케이터를 가져 와요-이게 루트 테스트 죠, 맞죠?

위와 동일한 코드이며 다음과 같이 변경됩니다.

  • 이제 URL은 다음과 같습니다 http://the-internet.herokuapp.com/tables. 두 가지 테스트가 있습니다.

  • 첫 번째 항목 인 "ID 및 클래스로 요소 찾기"에 대한 로케이터는 다음과 같습니다.

css_locator = '#table2 tbody .dues'
xpath_locator = "//table[@id='table2']//tr/td[contains(@class,'dues')]"

결과는 다음과 같습니다.

css total time 1000 repeats: 8.24s, per find: 8.24ms

xpath total time for 1000 repeats: 8.45s, per find: 8.45ms

차이 0.2 밀리 초.

"순회로 요소 찾기":

css_locator = '#table1 tbody tr td:nth-of-type(4)'
xpath_locator = "//table[@id='table1']//tr/td[4]"

결과:

css total time 1000 repeats: 9.29s, per find: 9.29ms

xpath total time for 1000 repeats: 8.79s, per find: 8.79ms

이번에는 0.5 밀리 초 (역으로, XPath는 "더 빨리"여기에서 밝혀졌다).

그래서 오년 이상 (더 나은 브라우저 엔진) 단지 로케이터 성능에 초점을 맞추고, 같은 테스트 베드합니다 (UI 등의 정렬과 같은 어떤 행동) - 실제적으로 CSS와 XPath를 사이에 차이가 없다.


그렇다면 xpath와 css 중 성능을 위해 선택해야 할 두 가지는 무엇입니까? 답은 간단합니다. . ID로 찾기를 .

간단히 말해서, 요소의 ID가 고유 한 경우 (사양에 따라야하는 것처럼) 그 값은 브라우저의 DOM 내부 표현에서 중요한 역할을하므로 일반적으로 가장 빠릅니다.

그러나 고유하고 상수 (예 : 자동 생성되지 않음) ID를 항상 사용할 수있는 것은 아니므로 "CSS가있는 경우 XPath가 필요한 이유는 무엇입니까?"


XPath의 장점

성능이 떨어지면 xpath가 더 나은 이유는 무엇입니까? 단순함 – 다목적 성 및 성능.

Xpath는 XML 문서 작업을 위해 개발 된 언어입니다. 따라서 css보다 훨씬 더 강력한 구성을 허용합니다.
예를 들어, 트리의 모든 방향으로 탐색-요소를 찾은 다음 해당 조부모로 이동하여 특정 속성을 가진 하위 항목을 검색합니다.
포함 된 부울 조건을 허용합니다. – cond1 and not(cond2 or not(cond3 and cond4)); 포함 된 선택기 – "이러한 속성을 가진 이러한 자식이있는 div를 찾은 다음 그에 따라 탐색"합니다.
XPath는 노드의 값 (텍스트)을 기반으로 검색을 허용합니다. 그러나이 관행에 눈살을 찌푸리는 것은 특히 잘못 구조화 된 문서에서 유용합니다 (동적 ID 및 클래스와 같이 밟아야 할 명확한 속성이 없음) 텍스트로 요소를 찾습니다. 내용) .

css의 스테핑은 확실히 더 쉽습니다. 단 몇 분만에 선택자를 작성할 수 있습니다. 그러나 며칠 사용 후 xpath의 힘과 가능성은 CSS를 빠르게 극복했습니다.
그리고 순전히 주관적입니다. 복잡한 CSS는 복잡한 xpath 표현식보다 읽기가 훨씬 더 어렵습니다.

Outro;)

마지막으로, 다시 매우 주관적입니다. 어떤 것을 선택해야합니까?

IMO는 옳고 그른 선택이 없습니다. 동일한 문제에 대한 다른 솔루션이며 작업에 더 적합한 것을 선택해야합니다.

XPath의 "팬"이기 때문에 내 프로젝트에서 두 가지를 혼합하여 사용하는 것을 부끄러워하지 않습니다. 가끔 CSS를 던지는 것이 훨씬 빠릅니다.


로그인 페이지가있는 노드는 몇 개입니까? 로그인 페이지는 일반적으로 매우 간단하므로 약간의 차이를 보셨을 것입니다.
pagep

다른 성능 테스트는 다른 브라우저에서 훨씬 더 큰 차이를 보여줍니다.
pagep

1
첫 번째 질문의 경우 DOM 스크린 샷이 답변에 있으며 페이지는 온라인 및 공개입니다. 첫 번째와 두 번째로 답을주의 깊게 읽으면 필자는 자주 인용되는 몇 안되는 비교 중 하나 인 elementalselenium과 동일한 테스트를 반복했습니다. 동일한 대상 및 로케이터를 사용하지만 5 년 이상의 최신 브라우저를 사용합니다. .
Todor Minakov

3
@TodorMinakov 그레이트 포스트 !!! 100 % 동의합니다. 또한 XPath 구문이 (적어도 저에게는) 우리 모두가 잘 알고있는 것과 비슷하기 때문에 더 자연 스럽다고 생각합니다. 그리고 그것은 파일 / 폴더 경로입니다. 그래서 저는 CSS 나 XPath에 대한 지식이없는 사람이 XPath를 훨씬 쉽게 배울 것이라고 생각합니다. 성능 차이는 미미하기 때문에 학습 곡선을 강력하게 고려해야한다고 생각합니다.
hfontanez

1
@hfontanez 감사합니다. 파일 시스템 구조와 큰 비유는 생각하지 못했습니다. 나는에 대한 작은 조금을 동의해야하는 단계-에 용이하지만 -는 XPath 구문은 조금 처음에 위협이 될 수 있습니다, 플러스 몇 가지 잡았다-의이 (색인을 []한 후 //, 예를 들어) . 그러나 학습과 사용의 첫날이 지나면 거의 모든 사람들이 학습 곡선의 전환점을 넘습니다. :) (css 단계는 허용 됩니다. IMHO) .
Todor Minakov

13

cssSelectorXPath 간의 논쟁은 Selenium 커뮤니티 에서 가장 주관적인 논쟁 중 하나로 남아있을 것 입니다. 지금까지 우리가 이미 알고있는 것은 다음과 같이 요약 할 수 있습니다.

  • cssSelector 를 선호하는 사람들은 (특히 Internet Explorer에서 실행할 때) 더 읽기 쉽고 빠르다고 말합니다.
  • XPath 를 선호하는 사람들 은 페이지를 가로 지르는 기능을 선전하지만 cssSelector 는 할 수 없습니다.
  • IE8과 같은 오래된 브라우저에서 DOM을 탐색하는 것은 cssSelector 에서는 작동하지 않지만 XPath 에서는 괜찮습니다 .
  • XPath 는 DOM (예 : 하위에서 상위로)까지 이동할 수있는 반면, cssSelector 는 DOM 아래로만 이동할 수 있습니다 (예 : 상위에서 하위로).
  • 그러나 이전 브라우저에서 cssSelector 를 사용 하여 DOM을 탐색 할 수 없다고해서 페이지 디자인이 좋지 않고 유용한 마크 업의 이점을 얻을 수 있다는 표시기이기 때문에 반드시 나쁜 것은 아닙니다.
  • Ben BurtoncssSelector 를 사용해야한다고 언급했습니다 . 이것이 애플리케이션이 구축되는 방식이기 때문입니다. 이렇게하면 테스트를 더 쉽게 작성하고, 이야기하고, 다른 사람들이 유지 관리 할 수 ​​있습니다.
  • Adam Goucher 는 먼저 ID에 초점을 맞춘 다음 cssSelector 에 초점을 맞추고 , 필요할 때만 XPath를 활용 하고 (예 : DOM을 살펴보기 ) XPath 는 고급 로케이터에 대해 항상 더 강력해질 것입니다.

Dave Haeffner두 개의 HTML 데이터 테이블이있는 페이지 에서 테스트 를 수행했습니다. 하나의 테이블은 유용한 속성 ( IDClass ) 없이 작성 되었고 다른 하나는 그들과 함께 작성되었습니다. 자동 테스트를 위해 XPath가 아닌 cssSelector 선택기를 사용해야하는 이유는 무엇입니까? 토론에서 테스트 절차 와이 실험의 결과를 자세히 분석했습니다 . . 이 실험은 각 로케이터 전략 이 브라우저에서 합리적으로 동일 하다는 것을 보여 주었지만 전체 그림을 적절하게 그리지 못했습니다. 다른 토론의 Dave Haeffner CSS의 대 X 경로, 현미경 아래언급했듯이, 엔드 투 엔드 테스트에서 play Sauce 시작 , 브라우저 시작 및 테스트중인 응용 프로그램 과의 지연 시간 에 다른 많은 변수가있었습니다 . 이 실험의 불행한 점은 한 드라이버가 다른 드라이버보다 빠를 수 있다는 것입니다 (예 : IE vs Firefox ). 실제로는 그렇지 않습니다. cssSelectorcssSelector 의 성능 차이에 대한 진정한 맛을 얻으려면 XPath, 우리는 더 깊이 파헤쳐 야했습니다. 성능 벤치마킹 유틸리티를 사용하면서 로컬 머신에서 모든 것을 실행했습니다. 또한 전체 테스트 실행이 아닌 특정 Selenium 작업에 중점을 두었고 여러 번 실행했습니다. 셀레늄에 대한 cssSelector 대 XPath 토론에서 구체적인 테스트 절차 와이 실험의 결과를 자세히 분석했습니다 . 그러나 테스트는 여전히 한 가지 측면, 즉 더 많은 브라우저 범위 (예 : Internet Explorer 9 및 10)와 더 크고 더 깊은 페이지에 대한 테스트가 누락되었습니다 .

다른 토론에서 Dave Haeffner Css Vs. X Path, Under a Microscope (Part 2) 는 필요한 벤치 마크가 가능한 최상의 방법으로 다루어 지도록 크고 깊은 페이지를 보여주는 예제 를 고려해야 합니다 .


테스트 설정

이 자세한 예를 보여주기 위해 Windows XP 가상 머신이 설정되고 Ruby (1.9.3) 가 설치되었습니다. 사용 가능한 모든 브라우저와 이에 상응하는 Selenium 용 브라우저 드라이버도 설치되었습니다. 벤치마킹을 위해 Ruby의 표준 lib benchmark가 사용되었습니다.


테스트 코드

require_relative 'base'
require 'benchmark'

class LargeDOM < Base

  LOCATORS = {
    nested_sibling_traversal: {
      css: "div#siblings > div:nth-of-type(1) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3) > div:nth-of-type(3)",
      xpath: "//div[@id='siblings']/div[1]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]/div[3]"
    },
    nested_sibling_traversal_by_class: {
      css: "div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1 > div.item-1",
      xpath: "//div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]/div[contains(@class, 'item-1')]"
    },
    table_header_id_and_class: {
      css: "table#large-table thead .column-50",
      xpath: "//table[@id='large-table']//thead//*[@class='column-50']"
    },
    table_header_id_class_and_direct_desc: {
      css: "table#large-table > thead .column-50",
      xpath: "//table[@id='large-table']/thead//*[@class='column-50']"
    },
    table_header_traversing: {
      css: "table#large-table thead tr th:nth-of-type(50)",
      xpath: "//table[@id='large-table']//thead//tr//th[50]"
    },
    table_header_traversing_and_direct_desc: {
      css: "table#large-table > thead > tr > th:nth-of-type(50)",
      xpath: "//table[@id='large-table']/thead/tr/th[50]"
    },
    table_cell_id_and_class: {
      css: "table#large-table tbody .column-50",
      xpath: "//table[@id='large-table']//tbody//*[@class='column-50']"
    },
    table_cell_id_class_and_direct_desc: {
      css: "table#large-table > tbody .column-50",
      xpath: "//table[@id='large-table']/tbody//*[@class='column-50']"
    },
    table_cell_traversing: {
      css: "table#large-table tbody tr td:nth-of-type(50)",
      xpath: "//table[@id='large-table']//tbody//tr//td[50]"
    },
    table_cell_traversing_and_direct_desc: {
      css: "table#large-table > tbody > tr > td:nth-of-type(50)",
      xpath: "//table[@id='large-table']/tbody/tr/td[50]"
    }
  }

  attr_reader :driver

  def initialize(driver)
    @driver = driver
    visit '/large'
    is_displayed?(id: 'siblings')
    super
  end

  # The benchmarking approach was borrowed from
  # http://rubylearning.com/blog/2013/06/19/how-do-i-benchmark-ruby-code/
  def benchmark
    Benchmark.bmbm(27) do |bm|
      LOCATORS.each do |example, data|
    data.each do |strategy, locator|
      bm.report(example.to_s + " using " + strategy.to_s) do
        begin
          ENV['iterations'].to_i.times do |count|
         find(strategy => locator)
          end
        rescue Selenium::WebDriver::Error::NoSuchElementError => error
          puts "( 0.0 )"
        end
      end
    end
      end
    end
  end

end

결과

참고 : 출력은 초 단위이며 결과는 총 100 회 실행 시간에 대한 것입니다.

테이블 형식 :

css_xpath_under_microscopev2

차트 형식 :

  • 크롬 :

차트 크롬

  • Firefox :

차트 파이어 폭스

  • Internet Explorer 8 :

chart-ie8

  • Internet Explorer 9 :

chart-ie9

  • Internet Explorer 10 :

chart-ie10

  • 오페라 :

차트 오페라


결과 분석

  • Chrome과 Firefox는 더 빠른 cssSelector 성능을 위해 명확하게 조정되었습니다 .
  • Internet Explorer 8은 작동하지 않는 cssSelector잡동사니 , ~ 65 초가 소요 되는 제어 할 수없는 XPath 순회, 비교할 cssSelector 결과 가없는 38 초의 테이블 순회입니다 .
  • IE 9 및 10에서는 XPath 가 전반적으로 더 빠릅니다. Safari에서는 XPath 를 사용한 두 번의 느린 순회 실행을 제외하고는 엉망 입니다. 그리고 거의 모든 브라우저에서 XPath 로 수행 되는 중첩 된 형제 순회테이블 셀 순회 는 비용이 많이 드는 작업입니다.
  • 로케이터가 깨지기 쉽고 비효율적이며이를 피해야하므로 이는 놀라운 일이 아닙니다.

요약

  • 전반적으로 XPathcssSelector 보다 현저하게 느린 두 가지 상황이 있습니다 . 그러나 그들은 쉽게 피할 수 있습니다.
  • 성능 차이는 약간 유리합니다. IE가 아닌 브라우저의 경우 IE 브라우저의 경우.

하찮은 일

당신은 사용하여 벤치 마크 스스로를 수행 할 수있는 이 라이브러리 데이브 Haeffner이 모든 코드를 싸서.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.