簡體   English   中英

Java:調用名稱存儲在變量中的方法

[英]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或利益相關者? 對我而言,讓非技術人員參與測試自動化活動是沒有意義的。 任何自動化都需要良好的技術技能(包括編程和開發)。 否則,失敗概率非常高。

無論如何,你的問題更多的是stringsfunctional 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM