我正在使用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");
答案 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")));`
并在我的测试中获得干净的语法和可用的错误消息。