2013-10-30 3 views
0

일부 JavaScript가 포함 된 웹 페이지가 있고 일부 Ajax 호출을 수행합니다. Selenium을 사용하여 테스트 할 때, 나는 "PHPUnit_Extensions_Selenium2TestCase_WebDriverException : 엘리먼트가 DOM에 더 이상 첨부되어 있지 않다"라는 메시지를 무작위로 얻습니다. 아마 5 회에 한 번 실행됩니다.또 다른 WebDriverException : 요소가 더 이상 DOM에 연결되지 않았습니다.

이제 Ajax 호출과 테스트 엔진 간의 경쟁 문제에 대해 알고 있고 이에 대한 보호 조치를 취했지만 여전히 문제가 있습니다. 내 시나리오는 다음과 같습니다. select 요소 2의 모든 옵션 하위 요소를 제거하고 Ajax 응답을 기반으로 새로운 옵션 하위 요소를 생성하는 Ajax 호출을 트리거하는 select 요소 1의 값을 변경합니다. 테스트 코드 :

$this->select($this->byId('select1'))->selectOptionByValue('value1'); 
    $this->myWaitForElementToAppear('#select2>option[value="value2"]'); 
    $this->select($this->byId('select2'))->selectOptionByValue('value2'); 

마지막 줄에서 오류가 트리거됩니다. 내가 잘못 본게 아니라면

public function myWaitForElementToAppear($selector, $limit = 5) { 
    $start = time(); 
    while(true) { 
     if($start + $limit < time()) { 
      break; 
     } 
     try { 
      $this->byCssSelector($selector); 
      break; 
     } catch(PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {} 
    } 
} 

이 myWaitForElementToAppear 방법이 종료하기 전에 원하는 옵션이 jQuery를에 의해 추가 된 보장하고, 따라서이 다음 줄에 사용할 수 있도록해야합니다 여기에 myWaitForElementToAppear 방법입니다. 나는 시간 제한이 여기에서 일어나지 않는다는 것을 확실히해야한다고 덧붙여 야한다. (나의 방법은 그것이 일어나는 것을 허용하기 때문에) 그리고 나는 그것이 사실이 아니라는 점에 긍정적이다.

편집 : 나는 그 퍼팅 수면을 추가해야한다. (1) myWaitForElementToAppear 호출 후 문제가 해결되지만 추가 초가 필요한 이유를 알 수 없습니다. myWaitForElementToAppear를 호출하면 안됩니다.

답변

1

몇 가지 설명 here 있습니다

첫째, 시간()는 매우 모호 모든 일을하게 통과 전체 초 수를 반환, 매우 낮은 정밀도를 가지고있다. 둘째로, PHP는 수천 번 루핑하면서 앉아야 만하고 기다림으로써 근본적으로 아무 것도하지 않습니다. 더 나은 해결책은 두 개의 스크립트 절전 함수, sleep() 및 usleep() 중 하나 인 이 유일한 매개 변수로 실행을 일시 중지하는 데 걸리는 시간을 사용하는 것입니다. php.net에서

:

수면과 usleep의 아이디어는 다른 프로그램이 자신의 실행 일부 사이클을 가질 수 있도록 CPU를 시켜서 몇 유휴 사이클을 실행하는 것입니다. 을 사용하면 응답 시간이 단축되고 전체 시스템 부하가 낮아집니다. 그래서 뭔가를 기다려야한다면 기다리는 동안 절대적으로 아무것도하지 않고 CPU를 사용하는 대신 몇 초 동안 잠을 자다가 이됩니다.

그리고 당신은 phpunit을에서 waitUntil를 사용할 수는 :

/* waitElementToDisappear */ 
$this->waitUntil(function($testCase) { 
    try { 
     $input = $testCase->byCssSelector("#select2>option[value="value2"]"); 
    } catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) { 
     if (PHPUnit_Extensions_Selenium2TestCase_WebDriverException::NoSuchElement == $e->getCode()) { 
      return true; 
     } 
    } 
}, 5000); 

/* waitElementToAppear */ 
$this->waitUntil(function($testCase) { 
    try { 
     $input = $testCase->byCssSelector("#select2>option[value="value2"]"); 
     return true; 
    } catch (PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) {} 
}, 5000); 
+0

그 시간이 내 문제라고 생각하지 않습니다. 그것의 유일한 목적은 JavaScript가 마술을하기를 기다리는 동안 (약) 5 초 이상을 소비하지 못하게하는 것입니다. 왜냐하면 그 이상으로 충분해야하기 때문입니다. 또한 DOM에서 요소를 찾지 못하는 주된 문제를 해결할 때까지는 CPU를 해제 할 필요가 없습니다. 이미 DOM에 있어야합니다. 코드를 올바르게 읽는다면 요소가없는 경우 true를 반환합니다. 이는 필자가 원하는 것과 정반대입니다. 나는 $ input = 라인에 던져지지 않는 예외를 필요로한다. – Ajant

+0

요소가 발견 된 경우 (예외가 발생하지 않은 경우) 코드를 true로 반환하면 기본적으로 내 기능과 동일한 기능을 수행하며 불행히도 나를 위해 작동하지 않습니다. 이유, 내가 여기에 게시 처음에. 나는 당신의 대답을 잘못 읽고 있습니까? – Ajant

+0

당신은 _myWaitForElementToAppear_ 부르지 만, 우리에게 보여 _myWaitForElementToDisappear_ 그냥 _return true_ 이동 후 _ $ 입력 = _ waitUntil – rNix

관련 문제