[英]Java: call a method with name stored in variable
我有一個要求:
String command = "click"; // this can have value such as clear, getLocation, getSize, getTagName etc.
WebDriver driver = new ChromeDriver(options); //creating a webdriver object
driver.findElement(By.id("id1")).click(); //Here I want "click" method should be called dynamically as per what I have stored in variable `command`.
那么,是否有可能像:
driver.findElement(By.id("id1")).<something to call click()>
我已經看過Java中的Reflection,但根據我的要求,這看起來很復雜。 任何指針都會有所幫助!
您的變量表示您要對Web元素執行的操作(在本例中,單擊它)。
適當的類型不是String
。 改為使用Consumer<WebElement>
(或者driver.findElement()
返回的類型):
Consumer<WebElement> command = e -> e.click();
// ...
command.accept(driver.findElement(By.id("id1")));
這是類型安全,高效,可重構,並且比反射更靈活(因為您的消費者可以使用元素做任何想做的事情,不限於沒有任何參數的單個方法調用。例如,在文本中輸入一些文本領域)
最簡單的方法是使用反射:
String command = "click";
WebElement element = driver.findElement(By.id("id1"));
Method method = WebElement.class.getMethod(command);
method.invoke(element);
如果你By.id
用反射調用By.id
,那么你可以這樣做:
String command = "click";
String id = "id";
Method byMethod = By.class.getMethod(id, String.class);
WebElement element = driver.findElement((By) byMethod.invoke(null, "id1"));
Method method = WebElement.class.getMethod(command);
method.invoke(element);
在設計方面(可能這可以進一步優化和抽象),你可以定義一個Enum
,讓我們將它命名為Action
:
public enum Action {
CLICK,
SENDKEY,
etc
}
在您的代碼中,然后執行:
Action action = <input>;
// find the element
WebElement element = driver.findElement(By.id("id1"));
switch(action) {
case CLICK:
element.click();
break;
case SENDKEY:
element.sendKey();
break;
...
default:
System.out.println("Undefined action");
break;
}
看起來你正在嘗試構建一個關鍵字驅動的框架。 說實話,聽到任何有關成功的故事,我都會感到非常驚訝。 總是想知道這種框架的真正目的是什么? 誰會用它? 經理,手工QA或利益相關者? 對我而言,讓非技術人員參與測試自動化活動是沒有意義的。 任何自動化都需要良好的技術技能(包括編程和開發)。 否則,失敗概率非常高。
無論如何,你的問題更多的是strings
與functional interfaces
映射,或非常智能的反射使用。 但主要問題是你為此選擇了錯誤的API [輸入]。 以下行:
driver.findElement(locator).doSmth();
是一種正確的失敗方法,因為findElement
使用隱式等待。 當你面對NoSuchElementException
/ StaleElementReferenceException
時,我100%肯定你會開始全局重構/修改實現的方法。
常識建議使用ExpectedConditions
進行流暢的等待。 但它會使你的任務變得更加復雜,因為除了定位器和動作之外你還要考慮應該由用戶提供的條件。
從技術角度來說,我首先創建公共包裝器來封裝低級WebDriver API調用。 與原始調用相比,映射或反映此類函數要容易得多。 例如,預期條件可能隱藏在枚舉級別上:
@Getter
@RequiredArgsConstructor
public enum WaitCondition {
visible(ExpectedConditions::visibilityOfElementLocated),
enabled(ExpectedConditions::elementToBeClickable);
private final Function<By, ExpectedCondition<WebElement>> type;
}
通過調用例如WaitCondition.valueOf("visible")
來檢索所需的常量將很容易,其中輸入字符串可以從外部傳遞。
通用API包裝器可能如下所示:
protected void click(By locator) {
click(locator, enabled);
}
protected void click(By locator, WaitCondition condition) {
waitFor(locator, condition).click();
}
private WebElement waitFor(By locator, WaitCondition condition) {
return wait.until(condition.getType().apply(locator));
}
此線程中的其他人已經提供了映射/反射示例。 請注意:如果您更喜歡反射,我建議您查看jOOR庫,這樣可以簡化此過程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.