Careeroza
Choosing the Best Locator
Priority Order
- id (if it is unique and not auto-generated like
input-4821) - name or a dedicated test attribute:
data-testid="add-to-cart" - CSS selector (short and readable)
- XPath (when you need text or to move up/sideways in the DOM)
- linkText for links, className / tagName for lists
Tip: Ask developers to add data-testid attributes. They do not change when the design changes, so tests stop breaking.
Good and Bad Locators
| Locator | Verdict | Why |
|---|---|---|
By.id("add-to-cart") | good | unique, meaningful |
By.cssSelector("[data-testid='cart-count']") | good | made for tests |
By.id("ember1423") | bad | generated, changes every load |
By.xpath("/html/body/div[2]/div[3]/form/button") | bad | breaks if any div is added |
By.className("col-md-4") | bad | layout class, matches many elements |
Scoring Locators
Example
A small program that flags risky locators, using the rules above:
import java.util.*;
public class Main {
static String review(String type, String value) {
if (type.equals("id") && value.matches(".*[0-9]{3,}.*")) return "RISKY: looks auto-generated";
if (type.equals("xpath") && value.startsWith("/html")) return "RISKY: absolute XPath";
if (type.equals("className") && value.startsWith("col-")) return "RISKY: layout class";
return "OK";
}
public static void main(String[] args) {
String[][] locators = {
{"id", "add-to-cart"}, {"id", "ember1423"},
{"xpath", "/html/body/div[2]/form/button"}, {"xpath", "//button[text()='Login']"},
{"className", "col-md-4"}, {"cssSelector", "#cart-count"}
};
for (String[] l : locators) {
System.out.printf("%-12s %-32s %s%n", l[0], l[1], review(l[0], l[1]));
}
}
}Output
id add-to-cart OK id ember1423 RISKY: looks auto-generated xpath /html/body/div[2]/form/button RISKY: absolute XPath xpath //button[text()='Login'] OK className col-md-4 RISKY: layout class cssSelector #cart-count OK