首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何断言断言A或断言B传递给Junit 4?

我如何断言断言A或断言B传递给Junit 4?
EN

Stack Overflow用户
提问于 2014-10-14 21:54:04
回答 2查看 2.1K关注 0票数 0

我正在使用Junit 4w/ Selenium WebDriver进行一些自动化测试。我有一个测试,它记录一个页面上的一些值,单击页面上的一个按钮来加载下一个页面,然后比较记录的值以确保它们发生了变化。

问题是,这是一对值,其中只有一个必须改变,而不是两者兼而有之。

为了测试它,我目前实现了以下代码:

代码语言:javascript
复制
boolean orderNumberChanged = true;
try
{
  assertThat(orderNumber,
             is(not(getValueForElement(By.name("updateForm:j_id35")))));

}
catch (AssertionError ae) { orderNumberChanged = false; }
try
{
  assertThat(orderDate,
             is(not(getValueForElement(By.name("updateForm:j_id37")))));

}
catch (AssertionError ae)
{
  if ( !orderNumberChanged )
  { fail("OrderNumber and OrderDate didn't change."); }
}

虽然它应该工作得很好,但在我看来,它看起来很难看,而且它的接缝应该有一些方法来断言类似的东西。

对于记录,getValueForElement()是我写来包装的方法。

driver.findElement(locator).getAttribute("value");

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-30 21:31:18

建议assertTrue(orderNumber.equals(...) || orderDate.equals(...));的答案/评论确实是最简单和最直接的解决方案。然而,我也想要更好的错误消息,而不仅仅是AssertionError

为了做到这一点并不是微不足道的。我正在使用Selenium WebDriver,因此正在检查的实际数据属于WebDriver对象。

我找到了答案,多亏了这篇文章:http://www.planetgeek.ch/2012/03/07/create-your-own-matcher/博客文章。

原来Hamcrest有一个CombinableMatcher类和一个CombinableEitherMatcher

最后,我复制了CombinableEitherMatcher的逻辑,创建了自己的类Neither

代码语言:javascript
复制
public class Neither<X> 
{
  /**
   * Creates a matcher that matches when neither of the specified matchers 
   * match the examined object.
   * <p/>
   * For example:
   * <pre>
   * assertThat("fan", neither(containsString("a")).nor(containsString("b")))
   * </pre>
   */
  public static <LHS> Neither<LHS> neither(Matcher<LHS> matcher)
  { return new Neither<LHS>(matcher); }

  private final Matcher<X> first;

  public Neither(Matcher<X> matcher) { this.first = not(matcher); }

  public CombinableMatcher<X> nor(Matcher<X> other)
  { return new CombinableMatcher<X>(first).or(not(other)); }

  /**
   *  Helper class to do the heavy lifting and provide a usable error
   *  from: http://www.planetgeek.ch/2012/03/07/create-your-own-matcher/
   */
  private class WebElementCombinableMatcher extends BaseMatcher<WebElement>
  {
     private final List<Matcher<WebElement>> matchers = new ArrayList<Matcher<WebElement>>();
     private final List<Matcher<WebElement>> failed = new ArrayList<Matcher<WebElement>>();

     private WebElementCombinableMatcher(final Matcher matcher)
     { matchers.add(matcher); }

     public WebElementCombinableMatcher and(final Matcher matcher) 
     {
        matchers.add(matcher);
        return this;
     }

     @Override
     public boolean matches(final Object item)
     {
        for (final Matcher<WebElement> matcher : matchers)
        {
           if (!matcher.matches(item))
           {
              failed.add(matcher);
              return false;
           }
        }
        return true;
     }

     @Override
     public void describeTo(final Description description)
     { description.appendList("(", " " + "and" + " ", ")", matchers); }

     @Override
     public void describeMismatch(final Object item, final Description description)
     {
        for (final Matcher<WebElement> matcher : failed)
        {
           description.appendDescriptionOf(matcher).appendText(" but ");
           matcher.describeMismatch(item, description);
        }
     }    

  }

}

这让我打电话给assertThat(driver, niether(matcher(x)).nor(matcher(y));

由于我试图比较从驱动程序中获得的特定WebElements,所以我不得不创建匹配器,可以在niether/nor内部使用。

例如:

代码语言:javascript
复制
public class WebElementValueMatcher extends FeatureMatcher<WebDriver, String>
{
   public static Matcher<WebDriver> elementHasValue(final By locator,
                                                    String elementValue)
   { return new WebElementValueMatcher(equalTo(elementValue), locator); }

   public static Matcher<WebDriver> elementHasValue(final By locator,
                                                    Matcher<String> matcher)
   { return new WebElementValueMatcher(matcher, locator); }

   By locator;

   public WebElementValueMatcher(Matcher<String> subMatcher, By locator)
   {
      super(subMatcher, locator.toString(), locator.toString());
      this.locator = locator;
   }

   public WebElementValueMatcher(Matcher<String> subMatcher,
                                 String featureDescription, String featureName)
   { super(subMatcher, featureDescription, featureName); }

   @Override
   protected String featureValueOf(WebDriver actual)
   { return actual.findElement(locator).getAttribute("value"); }

}

我还有另一个非常类似的名字叫actual.findElement(locator).getText(); in featureValueOf

不过,现在我可以直接打电话给

代码语言:javascript
复制
assertThat(driver, 
           niether(elementHasValue(By.id("foo"),"foo"))
              .nor(elementHasValue(By.id("bar"),"bar")));` 

并在我的测试中获得清晰的语法和可用的错误消息。

票数 0
EN

Stack Overflow用户

发布于 2014-10-14 22:13:05

如果没有严重的扭曲,就不可能像回到assertTrue那样让它的可读性大大降低。

就这么做

代码语言:javascript
复制
assertTrue(orderNumber.equals(...) || orderDate.equals(...));

新的assertThat需要与单个对象进行匹配,因此您必须将它们放入数组或其他东西中才能通过。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26371032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档