0

いくつかの JavaScript を含み、いくつかの Ajax 呼び出しを実行する Web ページがあります。Selenium を使用してテストしようとすると、「PHPUnit_Extensions_Selenium2TestCase_WebDriverException: Element is no longer attached to the DOM」というメッセージがランダムに表示されます。おそらく 5 回の実行に 1 回です。

今、私は Ajax 呼び出しとテスト エンジンの間の競合の問題を認識しており、それを防ぐための措置を講じましたが、まだいくつかの問題があります。私のシナリオは次のとおりです。 select 要素 1 の値を変更して、select 要素 2 のすべてのオプション サブ要素を削除し、Ajax レスポンスに基づいて新しいオプション サブ要素を生成する Ajax 呼び出しをトリガーします。テスト コード:

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

最後の行でエラーが発生します。myWaitForElementToAppear メソッドは次のとおりです。

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 呼び出しの後に sleep(1) を置くことで問題が解決することを追加する必要がありますが、追加の秒が必要な理由がわかりません。myWaitForElementToAppear を呼び出すだけで十分ではないでしょうか?

4

1 に答える 1

1

ここにいくつかの説明があります:

まず、 time() の精度は非常に低く、経過した秒数のみを返すため、全体が非常に曖昧になります。第 2 に、PHP は待機中に何千回もループし、基本的に何もしない必要があります。はるかに優れた解決策は、sleep() と usleep() という 2 つのスクリプト スリープ関数のうちの 1 つを使用することです。これらは実行を一時停止するのに時間がかかる唯一のパラメータです。

php.netから:

sleep と 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);
于 2013-11-01T10:24:37.260 に答える