| 定位器 | By 方法 | 優點 | 缺點 | 推薦指數 |
|---|---|---|---|---|
| ID | By.id("kw") | 唯一、最快、W3C 標準推薦 | 開發常忘加或動態生成 | ⭐⭐⭐⭐⭐ |
| Name | By.name("q") | 表單元素常有、相對穩定 | 可能重複、非唯一 | ⭐⭐⭐⭐ |
| Class Name | By.className("btn") | 樣式類常固定 | 極易重複、組合類名需用 CSS/XPath | ⭐⭐ |
| Tag Name | By.tagName("input") | 無屬性時兜底 | 極不精準、需配合屬性過濾 | ⭐ |
| Link Text | By.linkText("登入") | 超鏈接文字直觀 | 文字常變、多語言、重複 | ⭐⭐ |
| Partial Link Text | By.partialLinkText("登") | 模糊匹配 | 同 Link Text,更易匹配錯誤 | ⭐ |
| CSS Selector | By.cssSelector("#kw") | 語法豐富、效能好、前端熟悉 | 極複雜結構寫法晦澀 | ⭐⭐⭐⭐⭐ |
| XPath | By.xpath("//input[@id='kw']") | 最強大、支援父/兄/文本/軸向查找 | 效能較慢、脆弱 (結構微調即失效) | ⭐⭐⭐ |
id → **直接用 ID**。name → **用 Name**。data-testid / data-cy → **用 CSS `[data-testid='xxx']`** (最佳實踐:開發專門為測試加屬性)。//button[text()='提交']、//label[text()='用戶名']/following-sibling::input)。.form-group > input[name='email']、tr:nth-child(3) td:last-child)。// 多類名
button.btn-primary.btn-lg
// 屬性包含/開頭/結尾
input[name*='user'] // 包含
input[name^='first'] // 開頭
input[name$='name'] // 結尾
// 偽類
tr:nth-child(2) // 第2行
tr:nth-of-type(odd) // 奇數行
input:not([disabled]) // 未禁用
// 組合
form#login > div.field > input[type='text']
// 文本匹配 (含空白處理)
//button[normalize-space()='提交']
//span[contains(text(),'錯誤')]
// 屬性與邏輯
//input[@type='text' and @name='email']
//div[@class='panel' or @class='card']
// 軸向
//label[text()='密碼']/following-sibling::input[1]
//ul/li[last()]
//table//tr[position() > 1] // 跳過表頭
// 動態 ID 兜底
//div[starts-with(@id, 'user-') and ends-with(@id, '-panel')]
禁用隱式等待 (
driver.manage().timeouts().implicitlyWait(0))。
全程使用 顯式等待:
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement el = wait.until(ExpectedConditions.elementToBeClickable(By.id("submit")));
el.click();
public class LoginPage {
private final WebDriver driver;
private final By username = By.cssSelector("input[name='username']");
private final By password = By.cssSelector("input[name='password']");
private final By submit = By.cssSelector("button[type='submit']");
public LoginPage(WebDriver driver) { this.driver = driver; }
public void login(String user, String pwd) {
driver.findElement(username).sendKeys(user);
driver.findElement(password).sendKeys(pwd);
driver.findElement(submit).click();
}
}
「ID > data-* 屬性 > CSS > XPath」是穩健自動化的鐵律。強迫開發加上 data-testid 是提升測試可維護性最高 ROI 的動作。掌握 CSS/XPath 進階語法,配合顯式等待與 POM 封裝,即可構建抗脆弱的自動化體系。