0

Web サイトの自動化に取り組んでおり、コードでの xpath の使用を減らす方法を見つけようとしています。私のコードは次のようになります

    driver.findElement(By.xpath("//html/body/center/div/div/center/table/tbody/tr/td/form/table/tbody/tr[3]/td/input")).click();
    driver.findElement(By.xpath("//html/body/div/table/tbody/tr/td/table/tbody/tr/td/table/tbody/tr/td")).getText();
    driver.findElement(By.xpath("//html/body/div/table/tbody/tr/td/div[2]/div/div/div[4]/div/div/div")).click();
    driver.findElement(By.xpath("//html/body/div[3]/div/div/div/div[2]/div/span/ul[2]/li[6]/a")).click();
    /*driver.findElement(By.xpath("//html/body/div/div/div/div[3]/div/div[2]/div[2]/table/tbody/tr/td[3]/table/tbody/tr/td[2]/em/button")).click();
    WebElement editUserForm = driver.findElement(By.cssSelector("iframe[src*='editUserForm']"));

コードがみすぼらしく見えないように、これらの xpath を減らす方法はありますか? ここのメンバーの 1 人が、「絶対 xpath を使用しないでください」と提案してくれました。どういう意味ですか ?助けてください。また、これに役立つリンクがあれば教えてください。

xpath ポインタへの文字列を作成するファイルを作成して、その文字列をコードで使用することはできますか?

4

2 に答える 2

11

ページ オブジェクトに投資する必要があります。これは非常に便利なパターンです。

https://code.google.com/p/selenium/wiki/PageObjects

テストを実装から分離するのに役立ちます。つまり、テストはどのような手順が実行されたかを詳しく説明したままにしておく必要があり、実装 (「ページ オブジェクト」) はそれらの手順がどのように実行されたかを詳しく説明する必要があります。

XPath自体に関しては、はい、かなり悪く、信頼できません。おそらくIDEやFirebugなどのツールによって自動的に生成されたと思います。これらは今すぐ捨ててください。二度と使用しないでください。XPath のチュートリアルを読んでください。XPath の仕様も素晴らしい学習の場です。

まず、//html/bodyビットを落とします。これは不要であり、見栄えを悪くします。それがなくてもうまくいきます。

第二に、はい、絶対 XPath (つまり、位置に基づくもの) を持つことは良くありません。最初の XPath で:

//html/body/center/div/div/center/table/tbody/tr/td/form/table/tbody/tr[3]/td/input

その最終を参照してくださいtr[3]。その行の前に別の行 ( ) を貼り付けたらどうなるtrでしょうか? これは、XPath が次のようになることを意味します。

//html/body/center/div/div/center/table/tbody/tr/td/form/table/tbody/tr[4]/td/input

つまり、テストが壊れるということです。ただし、テストの機能が壊れているからではなく、テストの実装が壊れているためにテストが壊れます。テストはそれほど不安定であってはなりません。開発者があなたが望むものよりも上に固執したい場合、trあなたがテストしている実際のものを壊さない限り、あなたのテストは合格するはずです。

あなたはそれについて別のことを考えるべきです。その要素に到達する他の方法を考えてください。私がこれを持っているとしましょう:

<div id="divUpload">
<span class="uploadDetails">We only support the following files:
    <span class="docSpan">.doc</span>
    <span class="txtSpan">.txt</span>
</span>
<button type="submit">Upload the file<submit>
<div>

docSpanクラス名としてスパンを取得したい。

次のいずれかが可能です:

//div/span/span[1]

これは機能しますが、次のように変更するとどうなりますか。

<div id="divUpload">
<span class="uploadDetails">We only support the following files:
    <span class="excelSpan">.xls</span>
    <span class="docSpan">.doc</span>
    <span class="txtSpan">.txt</span>
</span>
<button type="submit">Upload the file<submit>
<div>

これは、[1]ビットが無効になったことを意味します。

だから私はできました:

//div/span[@class='uploadDetails']/span[text()='.doc']

つまり、必要spanなクラスがスパンの子から取り除かれるuploadDetails uploadDetailsクラスがスパンから完全に取り除かれた場合にのみ失敗します。

または、次のことができます。

//div/descendant::span[text()='.doc']

これは、スパンが完全に移動され、その「親」div の子ではなくなった場合にのみ失敗することを意味します。

肝心なのは、ポジションに依存しないことです。その要素の近くにあるものを考えてください。クラスで何かありますか?中にテキストが入っているものはありますか?近くにIDのあるものはありませんか?

于 2013-05-20T11:35:44.407 に答える
0

ここでも Y XPath Y CSS を使用しない

css=.uploadDetails > .docSpan -- .doc

css=.uploadDetails > .excelSpan -- .xls

css=.uploadDetails > .txtSpan -- .txt

単純

于 2014-04-03T09:22:49.527 に答える