2013-05-20 48 views
0

我正在自動化一個網站,我正試圖找到一種方法來減少在我的代碼中使用xpaths。 我的代碼看起來是這樣的如何消除Webdriver代碼中的xpaths?

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使我的代碼看起來不寒酸? 這裏的成員之一建議我「請不要使用絕對xpath」。這是什麼意思 ? 請幫忙。另外讓我知道是否有任何鏈接可以幫助我。

是否有可能創建一個文件,將一個字符串到xpath指針,然後我們可以在代碼中使用該字符串?

+2

當然,您的某些元素有一個id屬性。例如,如果其中一個表的ID爲「invoices」,則可以使用//表[@ id ='invoices']'切斷表軸步驟之前的所有內容。閱讀一些XPath教程,您仍然缺乏XPath的基礎知識,並可以在一小時內更改它。如果你想使用Selenium,選擇一些教程時堅持使用XPath 1.0,不支持新版本。 –

回答

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我想取出的是跨度的孩子一類uploadDetailsuploadDetails類被認爲失敗完全關閉跨度。

我也可以:

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

這意味着它一定會當跨度乾脆搬到了失敗,而不再是「父」的div的孩子。

底線是不依靠職位。想想那個元素附近有什麼。有什麼課程嗎?裏面有文字嗎?附近有ID嗎?

+0

同意。 @mac:我建議您自己介紹一下使用xpaths的方法(比其他方法更可靠),例如[w3c xpath教程](http://www.w3schools.com/xpath/)。 –

+0

謝謝大家,它對像我這樣的新手非常有幫助。我會盡管所有這些,也許會繼續工作。 – mac

0

這裏再次ŸŸXPath的不要去用CSS

CSS = .uploadDetails> .docSpan - .DOC

CSS = .uploadDetails> .excelSpan - .xls的

CSS = .uploadDetails> .txtSpan - .txt

簡單