如何判断断言A或断言B是否通过Junit 4?

时间:2014-10-14 21:54:05

标签: java junit selenium-webdriver

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

问题是它是 PAIR 的值,只有其中一个必须改变,而不是两者都改变​​。

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

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");

2 个答案:

答案 0 :(得分:1)

如果没有严重的扭曲,使得它比回归assertTrue的可读性低得多,你就不能采用Hamcrest风格。

只做

assertTrue(orderNumber.equals(...) || orderDate.equals(...));

新的assertThat需要匹配单个对象,因此您必须将它们放入数组或其他内容才能完成。

答案 1 :(得分:0)

建议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

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));

由于我试图比较从驱动程序获得的特定Web元素,我必须创建我可以在 niether / nor

中使用的匹配器

例如:

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"); }

}

我还有一个非常相似的人在 featureValueOf 中调用actual.findElement(locator).getText();

但现在我可以简单地致电

assertThat(driver, 
           niether(elementHasValue(By.id("foo"),"foo"))
              .nor(elementHasValue(By.id("bar"),"bar")));` 

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