【问题标题】:Using Matchers for Objects对对象使用匹配器
【发布时间】:2014-02-20 19:32:16
【问题描述】:

所以我正在尝试创建一个“TestClass”,它基本上可以保存我的 Matcher、实际结果、错误消息和测试标签。

然而,我慢慢开始意识到这可能是不可能的,但我觉得它应该是。

也许这里有人可以帮忙。

这是我想要做的:

public void runTest(){
        Assert.assertThat(testLabel + " " + errorMessage, actualResult, testToRun);
    }

或者,因为我正在做 Selenium 测试,所以像这样:

public void runTestAsWebElement(String attributeToCheck){
        Object tempActualResult;

        switch (attributeToCheck.toLowerCase()){
            case "isdisplayed()":
            case "isdisplayed":
                tempActualResult = ((WebElement) actualResult).isDisplayed();
                break;
            case "isselected":
            case "isselected()":
                tempActualResult = ((WebElement) actualResult).isSelected();
                break;
            case "isenabled":
            case "isenabled()":
                tempActualResult = ((WebElement) actualResult).isEnabled();
                break;
            case "text":
                tempActualResult = ((WebElement) actualResult).getText();
                break;
            default:
                tempActualResult = ((WebElement) actualResult).getAttribute(attributeToCheck);
        }

        Assert.assertThat(testLabel + " " + errorMessage, tempActualResult, testToRun);
    }

但是,我想知道,匹配器是否能够确定实际结果是字符串还是布尔值?或者它总是会失败,因为两个对象都被比较为对象,而不是字符串(不确定底层代码将如何执行)。

任何关于如何正确处理这种情况的建议将不胜感激!

只是为了提供一些上下文 - 我目前正在编写这样的代码:

Switch(whatToTest){
  case "eye portfolio tests":
    customCheckErrorMessages.add("The Eye Portfolio header doesn't match expected user's value");
    customCheckActualResults.add(eyePortfolioPage.eyePortfolioAccountHeader);
    customCheckExpectedResults.add(holder);
    customCheckTests.add(containsString(holder));
    customTestAttributeToTest.add("text");
    break;
    //just showing what my step looks like
  }

String actualResult = "";
        for(int x = 0; x < customCheckErrorMessages.size(); x++){
            try{
                switch (customTestAttributeToTest.get(x)){
                    case "text":
                        actualResult = customCheckActualResults.get(x).getText();
                        break;
                    default:
                        actualResult = customCheckActualResults.get(x).getAttribute(customTestAttributeToTest.get(x));
                        break;
                }
            }catch (IndexOutOfBoundsException e){
                //Assuming this field wasn't actually entered. Defaulting to getText
                actualResult = customCheckActualResults.get(x).getText();
            }

            System.out.println("Additional Test #" + (x+1));

            Assert.assertThat(customCheckErrorMessages.get(x) + " Expected: \"" + customCheckExpectedResults.get(x)
                    + "\", Actual: \"" + customCheckActualResults.get(x).getText().trim(),
                    actualResult.trim(),
                    customCheckTests.get(x));
        }

我想写这样的代码:

switch(whatIWantToTest){
  case "transaction tests":
    customTests.add(new TestClass("There should be at least one transaction appearing on the page", //error Message
                        "Looking For Transactions:", //Test Label
                        myOrdersPage.transactions.size(), //Actual Result
                        greaterThanOrEqualTo(1))); //Test to run (should contain expected result)
//Just showing what my step looks like
}

for (TestClass test : customTests){
            test.runTest();
        }

【问题讨论】:

  • 我真的不明白你想要做什么。你为什么要包装简单的测试?如果您真的想创建一个方法来运行断言,请为每种类型的断言创建 1 个方法(1 个方法断言它被显示,1 个方法断言它具有包含 X 的文本),等等。我在这里看到的只是一层多余的代码。
  • @MrTi - 我这样做是为了让我的 Cucumber Step 函数可以快速连续运行我的所有测试。主要是为了让我的测试代码更容易阅读
  • 为您更新的问题
  • 你是对的 MrTi,我想太多了,哈哈。我基本上只是将我所有的检查封装到一个为我处理它的类中:)
  • 嘿,这对我来说也不少见。我之前确实对代码进行了改进,即 don't 从字符串转到函数调用。它要求用户了解一些不容易理解的代码。调用testElementDisplayed(element) 比调用test("displayed", element) 清楚得多。多种功能并不是一件坏事。 (你可以让函数调用其他函数,这样你就不用复制/粘贴代码了)

标签: selenium junit matcher


【解决方案1】:

这是我决定使用的代码。如果有人有更好的建议,我很乐意听到:)

private String testType;
public String errorMessage,  testAttribute;
public WebElement actualResult;
public List<WebElement> actualResults;
public String providedStringValue = null;
public Boolean providedBooleanValue = null;
public Matcher testToRun;
public int attempts = 1;

//Empty Constructor
public TestCase() {
    errorMessage = "";
    testType = "";
    actualResult = null;
    actualResults = null;
    testToRun = null;
    providedStringValue = null;
    providedBooleanValue = null;
}

//Run Test as a String check
public TestCase(String errorMessage, String providedResult, Matcher testToRun){
    this.errorMessage = errorMessage;
    providedStringValue = providedResult;
    testType = "String";
    this.testToRun = testToRun;
}

//Run Test as a Boolean check
public TestCase(String errorMessage, Boolean providedResult, Matcher testToRun){
    this.errorMessage = errorMessage;
    providedBooleanValue = providedResult;
    testType = "Boolean";
    this.testToRun = testToRun;
}

//Run Test on a WebElement
public TestCase(String errorMessage, String testAttribute, WebElement actualResult, Matcher testToRun) {
    this.errorMessage = errorMessage;
    testType = "WebElement";
    this.testAttribute = testAttribute;
    this.actualResult = actualResult;
    this.testToRun = testToRun;
}

//Run Test on a List<WebElement>
public TestCase(String errorMessage, String testAttribute, List<WebElement> actualResults, Matcher testToRun) {
    this.errorMessage = errorMessage;
    testType = "List";
    this.testAttribute = testAttribute;
    this.actualResults = actualResults;
    this.testToRun = testToRun;
}

public void clearTest() {
    errorMessage = "";
    testType = "";
    testAttribute = "";
    actualResult = null;
    actualResults = null;
    testToRun = null;
    providedStringValue = null;
    providedBooleanValue = null;
}

public void runTest() {
    try {
        if (testType.equalsIgnoreCase("WebElement")) {
            runTestAsWebElement(testAttribute);
        } else if (testType.equalsIgnoreCase("List")) {
            runTestAsList(testAttribute);
        } else if(testType.equalsIgnoreCase("Boolean")){
            runTestAsBooleanCheck();
        } else if(testType.equalsIgnoreCase("String")){
            runTestAsStringCheck();
        } else {
            Assert.fail("Don't know how to run this test type");
        }
    } catch (StaleElementReferenceException e) {
        if (attempts < 5) {
            System.out.println("StaleElementReferenceException - Running test again");
            attempts++;
            runTest();
            return;
        } else {
            throw e;
        }
    }
    attempts = 1;
}

private void runTestAsStringCheck(){
    Assert.assertThat(errorMessage, providedStringValue, testToRun);
}

private void runTestAsBooleanCheck(){
    Assert.assertThat(errorMessage, providedBooleanValue, testToRun);
}

//Sometimes the actualResult is a WebElement which means the value to check is wrapped within another value.
private void runTestAsWebElement(String attributeToCheck) {
    Object actualResultHolder;

    switch (attributeToCheck.toLowerCase()) {
        case "exists":
        case "present":
            try{
                actualResult.isDisplayed(); //Forcing WebElement to look for element. If throws exception, element not found
                actualResultHolder = true;
            } catch (NoSuchElementException e){
                actualResultHolder = false;
            }
            break;
        case"display":
        case "displayed":
        case "isdisplayed()":
        case "isdisplayed":
            try{
                actualResultHolder = actualResult.isDisplayed();
            } catch (NoSuchElementException e){
                System.out.println("Element not found");
                throw e;
                //actualResultHolder = false;
            }
            break;
        case "selected":
        case "isselected":
        case "isselected()":
            actualResultHolder = actualResult.isSelected();
            break;
        case "enabled":
        case "isenabled":
        case "isenabled()":
            actualResultHolder = actualResult.isEnabled();
            break;
        case "text":
            actualResultHolder = actualResult.getText().trim();
            break;
        default:
            if (attributeToCheck.contains("css: ")) {//In case we want to test the css attribute instead of the HTML attribute
                attributeToCheck = attributeToCheck.split("css: ")[1];
                actualResultHolder = actualResult.getCssValue(attributeToCheck);
            } else {
                actualResultHolder = actualResult.getAttribute(attributeToCheck);
            }
    }

    Assert.assertThat(errorMessage + "\n Actual Result = \"" + actualResultHolder + "\" ", actualResultHolder, testToRun);
}

private void runTestAsList(String attributeToCheck) {
    switch (attributeToCheck.toLowerCase()) {
        case "size":
        case "size()":
            Assert.assertThat(errorMessage, actualResults.size(), testToRun);
            break;
        default:
            //do nothing - Test has to do with the list of elements.
            Assert.assertThat(errorMessage, actualResults, testToRun);
    }
}

然后,如果出于某种原因我需要一些其他类型的测试,我只需将其添加到类中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 2016-01-05
    • 1970-01-01
    • 2020-11-06
    • 1970-01-01
    • 2020-10-19
    相关资源
    最近更新 更多